提交 32cc2c52 authored 作者: tledkov's avatar tledkov

#1057, #1072 fix review comments: make test robust, fix join subquery case

上级 3c6b2309
......@@ -29,6 +29,7 @@ import org.h2.expression.condition.ConditionAndOr;
import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.ViewIndex;
import org.h2.message.DbException;
import org.h2.result.LazyResult;
import org.h2.result.LocalResult;
......@@ -43,6 +44,7 @@ import org.h2.table.IndexColumn;
import org.h2.table.JoinBatch;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.table.TableType;
import org.h2.table.TableView;
import org.h2.util.ColumnNamer;
import org.h2.util.StatementBuilder;
......@@ -722,6 +724,8 @@ public class Select extends Query {
@Override
protected ResultInterface queryWithoutCache(int maxRows, ResultTarget target) {
disableLazyForJoinSubqueries(topTableFilter.getJoin());
int limitRows = maxRows == 0 ? -1 : maxRows;
if (limitExpr != null) {
Value v = limitExpr.getValue(session);
......@@ -865,6 +869,16 @@ public class Select extends Query {
return null;
}
private void disableLazyForJoinSubqueries(TableFilter f) {
for (; f != null; f = f.getJoin()) {
if (f.getTable().getTableType() == TableType.VIEW) {
ViewIndex idx = (ViewIndex) f.getIndex();
idx.getQuery().setNeverLazy(true);
}
}
}
/**
* Reset the batch-join after the query result is closed.
*/
......
......@@ -285,7 +285,6 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
return findRecursive(first, last);
}
setupQueryParameters(session, first, last, intersection);
query.setNeverLazy(true);
ResultInterface result = query.query(0);
return new ViewCursor(this, result, first, last);
}
......
......@@ -927,6 +927,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestDefrag());
addTest(new TestTools());
addTest(new TestSampleApps());
addTest(new TestSubqueryPerformanceOnLazyExecutionMode());
runAddedTests(1);
}
......@@ -989,7 +990,6 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestUtils());
addTest(new TestValueHashMap());
addTest(new TestLocalResultFactory());
addTest(new TestSubqueryPerformanceOnLazyExecutionMode());
runAddedTests();
......
......@@ -21,6 +21,8 @@ import java.sql.Statement;
public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
/** Rows count. */
private static final int ROWS = 5000;
/** Test repeats when unexpected failure. */
private static final int FAIL_REPEATS = 5;
/**
* Run just this test.
......@@ -37,7 +39,6 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
try (Connection conn = getConnection("lazySubq")) {
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE one (x INTEGER, y INTEGER )");
try (PreparedStatement prep = conn.prepareStatement("insert into one values (?,?)")) {
for (int row = 0; row < ROWS; row++) {
prep.setInt(1, row / 100);
......@@ -48,6 +49,8 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
testSubqueryInCondition(stmt);
testSubqueryInJoin(stmt);
testSubqueryInJoinFirst(stmt);
testJoinTwoSubqueries(stmt);
}
}
finally {
......@@ -58,12 +61,7 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
public void testSubqueryInCondition(Statement stmt) throws Exception {
String sql = "SELECT COUNT (*) FROM one WHERE x IN (SELECT y FROM one WHERE y < 50)";
long tNotLazy = executeAndCheckResult(stmt, sql, false);
long tLazy = executeAndCheckResult(stmt, sql, true);
assertTrue("Lazy execution too slow. lazy time: "
+ tLazy + ", not lazy time: " + tNotLazy,
tNotLazy * 5 > tLazy);
checkExecutionTime(stmt, sql);
}
public void testSubqueryInJoin(Statement stmt) throws Exception {
......@@ -71,12 +69,59 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
"SELECT COUNT (one.x) FROM one " +
"JOIN (SELECT y AS val FROM one WHERE y < 50) AS subq ON subq.val=one.x";
long tNotLazy = executeAndCheckResult(stmt, sql, false);
long tLazy = executeAndCheckResult(stmt, sql, true);
checkExecutionTime(stmt, sql);
}
public void testSubqueryInJoinFirst(Statement stmt) throws Exception {
String sql =
"SELECT COUNT (one.x) FROM " +
"(SELECT y AS val FROM one WHERE y < 50) AS subq " +
"JOIN one ON subq.val=one.x";
checkExecutionTime(stmt, sql);
}
public void testJoinTwoSubqueries(Statement stmt) throws Exception {
String sql =
"SELECT COUNT (one_sub.x) FROM " +
"(SELECT y AS val FROM one WHERE y < 50) AS subq " +
"JOIN (SELECT x FROM one) AS one_sub ON subq.val=one_sub.x";
checkExecutionTime(stmt, sql);
}
/**
* Compare execution time when lazy execution mode is disabled and enabled.
* The execution time must be almost the same.
*/
private void checkExecutionTime(Statement stmt, String sql) throws Exception {
long totalNotLazy = 0;
long totalLazy = 0;
int successCnt = 0;
int failCnt = 0;
for (int i = 0; i < FAIL_REPEATS; ++i) {
long tNotLazy = executeAndCheckResult(stmt, sql, false);
long tLazy = executeAndCheckResult(stmt, sql, true);
totalNotLazy += tNotLazy;
totalLazy += tLazy;
assertTrue("Lazy execution too slow. lazy time: "
+ tLazy + ", not lazy time: " + tNotLazy,
tNotLazy * 5 > tLazy);
if (tNotLazy * 2 > tLazy) {
successCnt++;
if (i == 0) {
break;
}
} else {
failCnt++;
}
}
if (failCnt > successCnt) {
fail("Lazy execution too slow. Avg lazy time: "
+ (totalLazy / FAIL_REPEATS) + ", avg not lazy time: " + (totalNotLazy / FAIL_REPEATS));
}
}
/**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论