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