Skip to content

Commit

Permalink
Merge pull request #3941 from katzyn/spatial_index_cost
Browse files Browse the repository at this point in the history
Fix incorrect implementation of MVSpatialIndex.getCost()
  • Loading branch information
katzyn committed Dec 9, 2023
2 parents 515cd70 + 8f57775 commit 1f1ad76
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
10 changes: 10 additions & 0 deletions h2/src/docsrc/html/changelog.html
Expand Up @@ -21,6 +21,16 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #3940: Wrong estimation of a query execution cost with spatial index
</li>
<li>Issue #3931: MVStoreTool -dump throws a NullPointerException or returns binary data
</li>
<li>Issue #3910: Small error in the tutorial regarding full text search
</li>
<li>PR #3915: Improving search by compound indexes
</li>
<li>RP #3893: Fixed unit test is support en_GB locale
</li>
<li>Issue #2834: MERGE INTO fails with an error "Timeout trying to lock table"
</li>
<li>Issue #3883: Performance regression in 2.2.222
Expand Down
4 changes: 4 additions & 0 deletions h2/src/main/org/h2/index/Index.java
Expand Up @@ -596,6 +596,10 @@ protected final long getCostRangeIndex(int[] masks, long rowCount, TableFilter[]
rowsCost = rowsCost / 3;
tryAdditional = true;
break;
} else if ((mask & IndexCondition.SPATIAL_INTERSECTS) == IndexCondition.SPATIAL_INTERSECTS) {
rowsCost = 2 + rowsCost / 4;
tryAdditional = true;
break;
} else {
if (mask == 0) {
// Adjust counter of used columns (i)
Expand Down
12 changes: 1 addition & 11 deletions h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
Expand Up @@ -282,16 +282,6 @@ public MVTable getTable() {
public double getCost(SessionLocal session, int[] masks, TableFilter[] filters,
int filter, SortOrder sortOrder,
AllColumnsForPlan allColumnsSet) {
return getCostRangeIndex(masks, columns);
}

/**
* Compute spatial index cost
* @param masks Search mask
* @param columns Table columns
* @return Index cost hint
*/
public static long getCostRangeIndex(int[] masks, Column[] columns) {
// Never use spatial tree index without spatial filter
if (columns.length == 0) {
return Long.MAX_VALUE;
Expand All @@ -303,7 +293,7 @@ public static long getCostRangeIndex(int[] masks, Column[] columns) {
return Long.MAX_VALUE;
}
}
return 2;
return 10 * getCostRangeIndex(masks, dataMap.sizeAsLongMax(), filters, filter, sortOrder, true, allColumnsSet);
}

@Override
Expand Down
25 changes: 25 additions & 0 deletions h2/src/test/org/h2/test/scripts/indexes.sql
Expand Up @@ -410,3 +410,28 @@ SELECT * FROM TEST WHERE _ROWID_ >= 2 AND _ROWID_ <= 3;

DROP TABLE TEST;
> ok

CREATE TABLE P AS SELECT 1 ID, GEOMETRY 'POLYGON ((160 280, 240 280, 240 140, 160 140, 160 280))' G;
> ok

CREATE INDEX ID_IDX ON P(ID);
> ok

CREATE SPATIAL INDEX P_G_INDEX ON P(G);
> ok

CREATE TABLE T AS SELECT 1 ID, 'A' K, 'A' V;
> ok

CREATE INDEX T_K_IDX ON T(K);
> ok

EXPLAIN SELECT P.ID, G, MAX(CASE WHEN K = 'A' THEN V END) AS A, MAX(CASE WHEN K = 'B' THEN V END) AS B
FROM P JOIN T USING(ID)
WHERE K IN ('A', 'C')
AND G && GEOMETRY 'POLYGON ((198.5 186.5, 269.5 186.5, 269.5 115, 198.5 115, 198.5 186.5))'
GROUP BY P.ID;
>> SELECT "P"."ID", "G", MAX(CASE WHEN "K" = 'A' THEN "V" END) AS "A", MAX(CASE WHEN "K" = 'B' THEN "V" END) AS "B" FROM "PUBLIC"."T" /* PUBLIC.T_K_IDX: K IN('A', 'C') */ /* WHERE K IN('A', 'C') */ INNER JOIN "PUBLIC"."P" /* PUBLIC.ID_IDX: ID = PUBLIC.T.ID */ ON 1=1 WHERE (("K" IN('A', 'C')) AND ("G" && GEOMETRY 'POLYGON ((198.5 186.5, 269.5 186.5, 269.5 115, 198.5 115, 198.5 186.5))')) AND ("PUBLIC"."P"."ID" = "PUBLIC"."T"."ID") GROUP BY "P"."ID"

DROP TABLE P, T;
> ok

0 comments on commit 1f1ad76

Please sign in to comment.