提交 7ec1dbee authored 作者: Noel Grandin's avatar Noel Grandin

Issue #643: H2 doesn't use index when I use IN and EQUAL in one query

上级 89ef8874
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #643: H2 doesn't use index when I use IN and EQUAL in one query
</li>
<li>Reset transaction start timestamp on ROLLBACK <li>Reset transaction start timestamp on ROLLBACK
</li> </li>
<li>Issue #632: CREATE OR REPLACE VIEW creates incorrect columns names <li>Issue #632: CREATE OR REPLACE VIEW creates incorrect columns names
......
...@@ -131,9 +131,9 @@ public class IndexCursor implements Cursor { ...@@ -131,9 +131,9 @@ public class IndexCursor implements Cursor {
if (isIntersects) { if (isIntersects) {
intersects = getSpatialSearchRow(intersects, columnId, v); intersects = getSpatialSearchRow(intersects, columnId, v);
} }
if (isStart || isEnd) { // An X=? condition will produce less rows than
// an X=? condition will produce less rows than // an X IN(..) condition, unless the X IN condition can use the index.
// an X IN(..) condition if ((isStart || isEnd) && !canUseIndexFor(inColumn)) {
inColumn = null; inColumn = null;
inList = null; inList = null;
inResult = null; inResult = null;
...@@ -176,6 +176,10 @@ public class IndexCursor implements Cursor { ...@@ -176,6 +176,10 @@ public class IndexCursor implements Cursor {
// only one IN(..) condition can be used at the same time // only one IN(..) condition can be used at the same time
return false; return false;
} }
return canUseIndexFor(column);
}
private boolean canUseIndexFor(Column column) {
// The first column of the index must match this column, // The first column of the index must match this column,
// or it must be a VIEW index (where the column is null). // or it must be a VIEW index (where the column is null).
// Multiple IN conditions with views are not supported, see // Multiple IN conditions with views are not supported, see
......
...@@ -80,6 +80,7 @@ public class TestScript extends TestBase { ...@@ -80,6 +80,7 @@ public class TestScript extends TestBase {
} }
reconnectOften = !config.memory && config.big; reconnectOften = !config.memory && config.big;
testScript("testScript.sql"); testScript("testScript.sql");
testScript("query-optimisations.sql");
testScript("commands-dml-script.sql"); testScript("commands-dml-script.sql");
testScript("commands-dml-create-view.sql"); testScript("commands-dml-create-view.sql");
for (String s : new String[] { "array", "bigint", "binary", "blob", for (String s : new String[] { "array", "bigint", "binary", "blob",
......
-- Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
create table person(firstname varchar, lastname varchar);
> ok
create index person_1 on person(firstname, lastname);
> ok
insert into person select convert(x,varchar) as firstname, (convert(x,varchar) || ' last') as lastname from system_range(1,100);
> update count: 100
-- Issue #643: verify that when using an index, we use the IN part of the query, if that part of the query
-- can directly use the index.
--
explain analyze SELECT * FROM person WHERE firstname IN ('FirstName1', 'FirstName2') AND lastname='LastName1';
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT PERSON.FIRSTNAME, PERSON.LASTNAME FROM PUBLIC.PERSON /* PUBLIC.PERSON_1: FIRSTNAME IN('FirstName1', 'FirstName2') AND LASTNAME = 'LastName1' */ /* scanCount: 1 */ WHERE (FIRSTNAME IN('FirstName1', 'FirstName2')) AND (LASTNAME = 'LastName1')
> rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论