From dfe3960a42f619e1f3a51b6efb1f3e29a5ef8e12 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 11 Mar 2021 13:25:35 -0800 Subject: [PATCH] PHOENIX-6409 Include local index uncovered columns merge in explain plan. --- .../phoenix/end2end/CostBasedDecisionIT.java | 4 ++++ .../phoenix/end2end/index/LocalIndexIT.java | 13 +++++++++++ .../phoenix/end2end/index/MutableIndexIT.java | 1 + .../phoenix/end2end/index/ViewIndexIT.java | 1 + .../end2end/join/HashJoinLocalIndexIT.java | 3 +++ .../compile/ExplainPlanAttributes.java | 23 +++++++++++++++++-- .../apache/phoenix/iterate/ExplainTable.java | 9 ++++++++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java index c313393a91f..f95215afe27 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java @@ -361,10 +361,12 @@ public void testCostOverridesStaticPlanOrderingInUnionQuery() throws Exception { verifyQueryPlan(query, "UNION ALL OVER 2 QUERIES\n" + " CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" + + " SERVER MERGE [0.C2]\n" + " SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" <= 'z'\n" + " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" + " CLIENT MERGE SORT\n" + " CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" + + " SERVER MERGE [0.C2]\n" + " SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" >= 'a'\n" + " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" + " CLIENT MERGE SORT"); @@ -413,11 +415,13 @@ public void testCostOverridesStaticPlanOrderingInJoinQuery() throws Exception { // Use the optimal plan based on cost when stats become available. verifyQueryPlan(query, "CLIENT PARALLEL 626-WAY RANGE SCAN OVER " + tableName + " [1,'X0'] - [1,'X1']\n" + + " SERVER MERGE [0.C2]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + " SERVER SORTED BY [\"T1.:ROWKEY\"]\n" + "CLIENT MERGE SORT\n" + " PARALLEL INNER-JOIN TABLE 0\n" + " CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" + + " SERVER MERGE [0.C2]\n" + " SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" <= 'z'\n" + " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" + " CLIENT MERGE SORT\n" + diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java index 0a071ddb034..3b1c55451f2 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java @@ -309,6 +309,7 @@ public void testUseUncoveredLocalIndexWithPrefix() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + physicalTableName + " [1,3,4,3]\n" + + " SERVER MERGE [0.V3]\n" + " SERVER FILTER BY FIRST KEY ONLY AND \"V3\" = 1\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -338,6 +339,7 @@ public void testUseUncoveredLocalIndexWithSplitPrefix() throws Exception { assertEquals( "CLIENT PARALLEL 16-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,2,3]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -383,6 +385,7 @@ public void testUseUncoveredLocalIndex() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -403,6 +406,7 @@ public void testUseUncoveredLocalIndex() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,2]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -431,6 +435,7 @@ public void testUseUncoveredLocalIndex() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,2]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -441,6 +446,7 @@ public void testUseUncoveredLocalIndex() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,2]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY AND TO_INTEGER(\"V4\") = 4\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -451,6 +457,7 @@ public void testUseUncoveredLocalIndex() throws Exception { assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,2]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY AND \"V1\" = 3.0\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -661,6 +668,7 @@ public void testLocalIndexUsedForUncoveredOrderBy() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1]\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -683,6 +691,7 @@ public void testLocalIndexUsedForUncoveredOrderBy() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY REVERSE RANGE SCAN OVER " + indexPhysicalTableName + " [1]\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -778,6 +787,7 @@ public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName + " [1,'a']\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -801,6 +811,7 @@ public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName +" [1,*] - [1,'z']\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -837,6 +848,7 @@ public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName +" [1,*] - [1,'z']\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + " SERVER AGGREGATE INTO DISTINCT ROWS BY [\"V1\", \"T_ID\", \"K3\"]\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); @@ -865,6 +877,7 @@ public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception { assertEquals( "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName +" [1,*] - [1,'z']\n" + + " SERVER MERGE [0.K3]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"V1\"]\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java index 7a0e88dc36d..a15456c90e8 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java @@ -181,6 +181,7 @@ public void testCoveredColumnUpdates() throws Exception { query = "SELECT b.* from " + fullTableName + " where int_col1 = 4 AND char_col1 = 'chara'"; rs = conn.createStatement().executeQuery("EXPLAIN " + query); assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + fullTableName +" [1,'chara',4]\n" + + " SERVER MERGE [B.VARCHAR_COL2, B.CHAR_COL2, B.INT_COL2, B.DECIMAL_COL2, B.DATE_COL]\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); rs = conn.createStatement().executeQuery(query); assertTrue(rs.next()); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java index fe9e6f80258..85ea5ebcee7 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java @@ -239,6 +239,7 @@ public void testMultiTenantViewLocalIndex() throws Exception { ResultSet rs = conn1.prepareStatement("EXPLAIN " + sql).executeQuery(); assertEquals( "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + SchemaUtil.getPhysicalTableName(Bytes.toBytes(fullTableName), isNamespaceMapped) + " [1,'10',100]\n" + + " SERVER MERGE [0.V1]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs)); rs = conn1.prepareStatement(sql).executeQuery(); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java index bcc38ffda94..ff28c4b7da4 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java @@ -463,6 +463,7 @@ public static synchronized Collection data() { * WHERE s.name = 'S1' AND i.name < 'T6' */ "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,'S1']\n" + + " SERVER MERGE [0.PHONE]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT\n" + " PARALLEL INNER-JOIN TABLE 0\n" + @@ -479,6 +480,7 @@ public static synchronized Collection data() { * GROUP BY phone */ "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,'S1']\n" + + " SERVER MERGE [0.PHONE]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + " SERVER AGGREGATE INTO DISTINCT ROWS BY [\"S.PHONE\"]\n" + "CLIENT MERGE SORT\n" + @@ -495,6 +497,7 @@ public static synchronized Collection data() { * WHERE s.name <= 'S3' */ "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,*] - [1,'S3']\n" + + " SERVER MERGE [0.PHONE]\n" + " SERVER FILTER BY FIRST KEY ONLY\n" + " SERVER AGGREGATE INTO SINGLE ROW\n" + " PARALLEL LEFT-JOIN TABLE 0\n" + diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java index 855ce9639f7..4e5856ce6aa 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java @@ -18,9 +18,12 @@ package org.apache.phoenix.compile; +import java.util.Set; + import org.apache.hadoop.hbase.client.Consistency; import org.apache.phoenix.parse.HintNode; import org.apache.phoenix.parse.HintNode.Hint; +import org.apache.phoenix.schema.PColumn; /** * ExplainPlan attributes that contain individual attributes of ExplainPlan @@ -69,6 +72,7 @@ public class ExplainPlanAttributes { // For non-Join queries related Plans, rhsJoinQueryExplainPlan will always // be null private final ExplainPlanAttributes rhsJoinQueryExplainPlan; + private Set serverMergeColumns; private static final ExplainPlanAttributes EXPLAIN_PLAN_INSTANCE = new ExplainPlanAttributes(); @@ -107,6 +111,7 @@ private ExplainPlanAttributes() { this.clientCursorName = null; this.clientSortAlgo = null; this.rhsJoinQueryExplainPlan = null; + this.serverMergeColumns = null; } public ExplainPlanAttributes(String abstractExplainPlan, @@ -126,7 +131,8 @@ public ExplainPlanAttributes(String abstractExplainPlan, Integer clientOffset, Integer clientRowLimit, Integer clientSequenceCount, String clientCursorName, String clientSortAlgo, - ExplainPlanAttributes rhsJoinQueryExplainPlan) { + ExplainPlanAttributes rhsJoinQueryExplainPlan, + Set serverMergeColumns) { this.abstractExplainPlan = abstractExplainPlan; this.splitsChunk = splitsChunk; this.estimatedRows = estimatedRows; @@ -160,6 +166,7 @@ public ExplainPlanAttributes(String abstractExplainPlan, this.clientCursorName = clientCursorName; this.clientSortAlgo = clientSortAlgo; this.rhsJoinQueryExplainPlan = rhsJoinQueryExplainPlan; + this.serverMergeColumns = serverMergeColumns; } public String getAbstractExplainPlan() { @@ -294,6 +301,10 @@ public ExplainPlanAttributes getRhsJoinQueryExplainPlan() { return rhsJoinQueryExplainPlan; } + public Set getServerMergeColumns() { + return serverMergeColumns; + } + public static ExplainPlanAttributes getDefaultExplainPlan() { return EXPLAIN_PLAN_INSTANCE; } @@ -332,6 +343,7 @@ public static class ExplainPlanAttributesBuilder { private String clientCursorName; private String clientSortAlgo; private ExplainPlanAttributes rhsJoinQueryExplainPlan; + private Set serverMergeColumns; public ExplainPlanAttributesBuilder() { // default @@ -383,6 +395,7 @@ public ExplainPlanAttributesBuilder( this.clientSortAlgo = explainPlanAttributes.getClientSortAlgo(); this.rhsJoinQueryExplainPlan = explainPlanAttributes.getRhsJoinQueryExplainPlan(); + this.serverMergeColumns = explainPlanAttributes.getServerMergeColumns(); } public ExplainPlanAttributesBuilder setAbstractExplainPlan( @@ -580,6 +593,12 @@ public ExplainPlanAttributesBuilder setRhsJoinQueryExplainPlan( return this; } + public ExplainPlanAttributesBuilder setServerMergeColumns( + Set columns) { + this.serverMergeColumns = columns; + return this; + } + public ExplainPlanAttributes build() { return new ExplainPlanAttributes(abstractExplainPlan, splitsChunk, estimatedRows, estimatedSizeInBytes, iteratorTypeAndScanSize, @@ -592,7 +611,7 @@ public ExplainPlanAttributes build() { clientFilterBy, clientAggregate, clientSortedBy, clientAfterAggregate, clientDistinctFilter, clientOffset, clientRowLimit, clientSequenceCount, clientCursorName, - clientSortAlgo, rhsJoinQueryExplainPlan); + clientSortAlgo, rhsJoinQueryExplainPlan, serverMergeColumns); } } } diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java index 163364cefd1..c3ab8f1ade5 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java @@ -22,6 +22,7 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.Set; import org.apache.hadoop.hbase.client.Consistency; import org.apache.hadoop.hbase.client.Scan; @@ -44,6 +45,7 @@ import org.apache.phoenix.parse.HintNode.Hint; import org.apache.phoenix.query.KeyRange; import org.apache.phoenix.query.KeyRange.Bound; +import org.apache.phoenix.schema.PColumn; import org.apache.phoenix.schema.RowKeySchema; import org.apache.phoenix.schema.SortOrder; import org.apache.phoenix.schema.TableRef; @@ -178,6 +180,13 @@ protected void explain(String prefix, List planSteps, } } while (filterIterator.hasNext()); } + Set dataColumns = context.getDataColumns(); + if (dataColumns != null && !dataColumns.isEmpty()) { + planSteps.add(" SERVER MERGE " + dataColumns.toString()); + if (explainPlanAttributesBuilder != null) { + explainPlanAttributesBuilder.setServerMergeColumns(dataColumns); + } + } String whereFilterStr = null; if (whereFilter != null) { whereFilterStr = whereFilter.toString();