You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by la...@apache.org on 2019/12/24 14:26:07 UTC
[phoenix] branch 4.x-HBase-1.5 updated: PHOENIX-5096 Local index
region pruning is not working as expected.
This is an automated email from the ASF dual-hosted git repository.
larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.x-HBase-1.5 by this push:
new 1620c7d PHOENIX-5096 Local index region pruning is not working as expected.
1620c7d is described below
commit 1620c7d7f6b8ce8ccf38e27e6bff1182ec6f7985
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Tue Dec 24 06:26:39 2019 -0800
PHOENIX-5096 Local index region pruning is not working as expected.
---
.../phoenix/iterate/BaseResultIterators.java | 9 ++++
.../apache/phoenix/compile/QueryCompilerTest.java | 60 ++++++++++++++++++++++
2 files changed, 69 insertions(+)
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 45b4d4d..2dcc88b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -1023,6 +1023,15 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
endKey = regionBoundaries.get(regionIndex);
}
if (isLocalIndex) {
+ if (dataPlan != null && dataPlan.getTableRef().getTable().getType() != PTableType.INDEX) { // Sanity check
+ ScanRanges dataScanRanges = dataPlan.getContext().getScanRanges();
+ // we can skip a region completely for local indexes if the data plan does not intersect
+ if (!dataScanRanges.intersectRegion(regionInfo.getStartKey(), regionInfo.getEndKey(), false)) {
+ currentKeyBytes = endKey;
+ regionIndex++;
+ continue;
+ }
+ }
// Only attempt further pruning if the prefix range is using
// a skip scan since we've already pruned the range of regions
// based on the start/stop key.
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index e6337fa..b49aaf8 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -4870,6 +4870,66 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
}
@Test
+ public void testLocalIndexRegionPruning() throws SQLException {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ conn.createStatement().execute("CREATE TABLE T (\n" +
+ " A CHAR(1) NOT NULL,\n" +
+ " B CHAR(1) NOT NULL,\n" +
+ " C CHAR(1) NOT NULL,\n" +
+ " D CHAR(1),\n" +
+ " CONSTRAINT PK PRIMARY KEY (\n" +
+ " A,\n" +
+ " B,\n" +
+ " C\n" +
+ " )\n" +
+ ") SPLIT ON ('A','C','E','G','I')");
+
+ conn.createStatement().execute("CREATE LOCAL INDEX IDX ON T(D)");
+
+ // un-pruned, need to scan all six regions
+ String query = "SELECT * FROM T WHERE D = 'C'";
+ PhoenixStatement statement = conn.createStatement().unwrap(PhoenixStatement.class);
+ QueryPlan plan = statement.optimizeQuery(query);
+ assertEquals("IDX", plan.getContext().getCurrentTable().getTable().getName().getString());
+ plan.iterator();
+ assertEquals(6, plan.getScans().size());
+
+ // fixing first part of the key, can limit scanning to two regions
+ query = "SELECT * FROM T WHERE A = 'A' AND D = 'C'";
+ statement = conn.createStatement().unwrap(PhoenixStatement.class);
+ plan = statement.optimizeQuery(query);
+ assertEquals("IDX", plan.getContext().getCurrentTable().getTable().getName().getString());
+ plan.iterator();
+ assertEquals(2, plan.getScans().size());
+
+ // same with skipscan filter
+ query = "SELECT * FROM T WHERE A IN ('A', 'C') AND D = 'C'";
+ statement = conn.createStatement().unwrap(PhoenixStatement.class);
+ plan = statement.optimizeQuery(query);
+ assertEquals("IDX", plan.getContext().getCurrentTable().getTable().getName().getString());
+ plan.iterator();
+ assertEquals(3, plan.getScans().size());
+
+ // two parts of key fixed, need to scan a single region only
+ query = "SELECT * FROM T WHERE A = 'A' AND B = 'A' AND D = 'C'";
+ statement = conn.createStatement().unwrap(PhoenixStatement.class);
+ plan = statement.optimizeQuery(query);
+ assertEquals("IDX", plan.getContext().getCurrentTable().getTable().getName().getString());
+ plan.iterator();
+ assertEquals(1, plan.getScans().size());
+
+ // same with skipscan filter
+ query = "SELECT * FROM T WHERE A IN ('A', 'C') AND B = 'A' AND D = 'C'";
+ statement = conn.createStatement().unwrap(PhoenixStatement.class);
+ plan = statement.optimizeQuery(query);
+ assertEquals("IDX", plan.getContext().getCurrentTable().getTable().getName().getString());
+ plan.iterator();
+ assertEquals(2, plan.getScans().size());
+ }
+ }
+
+ @Test
public void testSmallScanForPointLookups() throws SQLException {
Properties props = PropertiesUtil.deepCopy(new Properties());
createTestTable(getUrl(), "CREATE TABLE FOO(\n" +