You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/04/16 16:32:04 UTC
[23/50] [abbrv] phoenix git commit: PHOENIX-1809 Improve explain plan
PHOENIX-1809 Improve explain plan
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/c823be99
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/c823be99
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/c823be99
Branch: refs/heads/calcite
Commit: c823be992460c4211bce713d7e24a125b108c2b8
Parents: 9bbd5ea
Author: James Taylor <jt...@salesforce.com>
Authored: Sat Apr 4 13:20:31 2015 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Sun Apr 5 14:07:51 2015 -0700
----------------------------------------------------------------------
.../org/apache/phoenix/end2end/HashJoinIT.java | 3 -
.../org/apache/phoenix/end2end/KeyOnlyIT.java | 2 +-
.../phoenix/end2end/QueryWithLimitIT.java | 2 +-
.../phoenix/iterate/BaseResultIterators.java | 2 +-
.../apache/phoenix/iterate/ExplainTable.java | 82 +++++++-------------
.../iterate/MergeSortTopNResultIterator.java | 1 -
.../java/org/apache/phoenix/util/ScanUtil.java | 19 ++++-
.../org/apache/phoenix/query/QueryPlanTest.java | 2 -
8 files changed, 50 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
index 596e5e9..1a2a1d0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
@@ -395,7 +395,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 4
*/
"CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
- " SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
@@ -777,7 +776,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 4
*/
"CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
- " SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
@@ -1179,7 +1177,6 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 4
*/
"CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
- " SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
" PARALLEL LEFT-JOIN TABLE 0\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/it/java/org/apache/phoenix/end2end/KeyOnlyIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/KeyOnlyIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/KeyOnlyIT.java
index 7470598..dca57b4 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/KeyOnlyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/KeyOnlyIT.java
@@ -180,7 +180,7 @@ public class KeyOnlyIT extends BaseOwnClusterClientManagedTimeIT {
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
assertEquals("CLIENT SERIAL 1-WAY FULL SCAN OVER KEYONLY\n" +
- " SERVER FILTER BY FIRST KEY ONLY AND PageFilter 1\n" +
+ " SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER 1 ROW LIMIT\n" +
"CLIENT 1 ROW LIMIT", QueryUtil.getExplainPlan(rs));
conn.close();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithLimitIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithLimitIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithLimitIT.java
index 437bf37..c05c92d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithLimitIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithLimitIT.java
@@ -74,7 +74,7 @@ public class QueryWithLimitIT extends BaseOwnClusterHBaseManagedTimeIT {
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
assertEquals("CLIENT SERIAL 1-WAY FULL SCAN OVER KEYONLY\n" +
- " SERVER FILTER BY FIRST KEY ONLY AND PageFilter 1\n" +
+ " SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER 1 ROW LIMIT\n" +
"CLIENT 1 ROW LIMIT", QueryUtil.getExplainPlan(rs));
} finally {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
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 9ac6a29..8d602b5 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
@@ -132,7 +132,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
}
public BaseResultIterators(QueryPlan plan, Integer perScanLimit) throws SQLException {
- super(plan.getContext(), plan.getTableRef(), plan.getGroupBy(), plan.getOrderBy(), plan.getStatement().getHint());
+ super(plan.getContext(), plan.getTableRef(), plan.getGroupBy(), plan.getOrderBy(), plan.getStatement().getHint(), plan.getLimit());
this.plan = plan;
StatementContext context = plan.getContext();
TableRef tableRef = plan.getTableRef();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
----------------------------------------------------------------------
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 2fcc2fb..3fe42fa 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
@@ -26,7 +26,6 @@ import java.util.NoSuchElementException;
import org.apache.hadoop.hbase.client.Consistency;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.Filter;
-import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
@@ -36,15 +35,17 @@ import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
+import org.apache.phoenix.filter.BooleanExpressionFilter;
import org.apache.phoenix.parse.HintNode;
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.types.PInteger;
-import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.RowKeySchema;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.util.ScanUtil;
import org.apache.phoenix.util.StringUtil;
import com.google.common.collect.Iterators;
@@ -57,17 +58,19 @@ public abstract class ExplainTable {
protected final GroupBy groupBy;
protected final OrderBy orderBy;
protected final HintNode hint;
+ protected final Integer limit;
public ExplainTable(StatementContext context, TableRef table) {
- this(context,table,GroupBy.EMPTY_GROUP_BY, OrderBy.EMPTY_ORDER_BY, HintNode.EMPTY_HINT_NODE);
+ this(context,table,GroupBy.EMPTY_GROUP_BY, OrderBy.EMPTY_ORDER_BY, HintNode.EMPTY_HINT_NODE, null);
}
- public ExplainTable(StatementContext context, TableRef table, GroupBy groupBy, OrderBy orderBy, HintNode hintNode) {
+ public ExplainTable(StatementContext context, TableRef table, GroupBy groupBy, OrderBy orderBy, HintNode hintNode, Integer limit) {
this.context = context;
this.tableRef = table;
this.groupBy = groupBy;
this.orderBy = orderBy;
this.hint = hintNode;
+ this.limit = limit;
}
private boolean explainSkipScan(StringBuilder buf) {
@@ -98,7 +101,6 @@ public abstract class ExplainTable {
protected void explain(String prefix, List<String> planSteps) {
StringBuilder buf = new StringBuilder(prefix);
ScanRanges scanRanges = context.getScanRanges();
- boolean hasSkipScanFilter = false;
Scan scan = context.getScan();
if (scan.getConsistency() != Consistency.STRONG){
@@ -113,7 +115,7 @@ public abstract class ExplainTable {
if (scanRanges.isEverything()) {
buf.append("FULL SCAN ");
} else {
- hasSkipScanFilter = explainSkipScan(buf);
+ explainSkipScan(buf);
}
buf.append("OVER " + tableRef.getTable().getPhysicalName().getString());
if (!scanRanges.isPointLookup()) {
@@ -121,48 +123,31 @@ public abstract class ExplainTable {
}
planSteps.add(buf.toString());
- Filter filter = scan.getFilter();
- PageFilter pageFilter = null;
- if (filter != null) {
- int offset = 0;
- boolean hasFirstKeyOnlyFilter = false;
- String filterDesc = "";
- if (hasSkipScanFilter) {
- if (filter instanceof FilterList) {
- List<Filter> filterList = ((FilterList) filter).getFilters();
- if (filterList.get(0) instanceof FirstKeyOnlyFilter) {
- hasFirstKeyOnlyFilter = true;
- offset = 1;
- }
- if (filterList.size() > offset+1) {
- filterDesc = filterList.get(offset+1).toString();
- pageFilter = getPageFilter(filterList);
- }
- }
- } else if (filter instanceof FilterList) {
- List<Filter> filterList = ((FilterList) filter).getFilters();
- if (filterList.get(0) instanceof FirstKeyOnlyFilter) {
- hasFirstKeyOnlyFilter = true;
- offset = 1;
- }
- if (filterList.size() > offset) {
- filterDesc = filterList.get(offset).toString();
- pageFilter = getPageFilter(filterList);
- }
- } else {
+ Iterator<Filter> filterIterator = ScanUtil.getFilterIterator(scan);
+ if (filterIterator.hasNext()) {
+ PageFilter pageFilter = null;
+ FirstKeyOnlyFilter firstKeyOnlyFilter = null;
+ BooleanExpressionFilter whereFilter = null;
+ do {
+ Filter filter = filterIterator.next();
if (filter instanceof FirstKeyOnlyFilter) {
- hasFirstKeyOnlyFilter = true;
- } else {
- filterDesc = filter.toString();
+ firstKeyOnlyFilter = (FirstKeyOnlyFilter)filter;
+ } else if (filter instanceof PageFilter) {
+ pageFilter = (PageFilter)filter;
+ } else if (filter instanceof BooleanExpressionFilter) {
+ whereFilter = (BooleanExpressionFilter)filter;
}
- }
- if (filterDesc.length() > 0) {
- planSteps.add(" SERVER FILTER BY " + (hasFirstKeyOnlyFilter ? "FIRST KEY ONLY AND " : "") + filterDesc);
- } else if (hasFirstKeyOnlyFilter) {
+ } while (filterIterator.hasNext());
+ if (whereFilter != null) {
+ planSteps.add(" SERVER FILTER BY " + (firstKeyOnlyFilter == null ? "" : "FIRST KEY ONLY AND ") + whereFilter.toString());
+ } else if (firstKeyOnlyFilter != null) {
planSteps.add(" SERVER FILTER BY FIRST KEY ONLY");
}
- if (pageFilter != null) {
- planSteps.add(" SERVER " + pageFilter.getPageSize() + " ROW LIMIT");
+ if (!orderBy.getOrderByExpressions().isEmpty() && groupBy.isEmpty()) { // with GROUP BY, sort happens client-side
+ planSteps.add(" SERVER" + (limit == null ? "" : " TOP " + limit + " ROW" + (limit == 1 ? "" : "S"))
+ + " SORTED BY " + orderBy.getOrderByExpressions().toString());
+ } else if (pageFilter != null) {
+ planSteps.add(" SERVER " + pageFilter.getPageSize() + " ROW LIMIT");
}
}
Integer groupByLimit = null;
@@ -173,13 +158,6 @@ public abstract class ExplainTable {
groupBy.explain(planSteps, groupByLimit);
}
- private PageFilter getPageFilter(List<Filter> filterList) {
- for (Filter filter : filterList) {
- if (filter instanceof PageFilter) return (PageFilter)filter;
- }
- return null;
- }
-
private void appendPKColumnValue(StringBuilder buf, byte[] range, Boolean isNull, int slotIndex) {
if (Boolean.TRUE.equals(isNull)) {
buf.append("null");
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
index 64ededa..71259e0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
@@ -91,7 +91,6 @@ public class MergeSortTopNResultIterator extends MergeSortResultIterator {
@Override
public void explain(List<String> planSteps) {
resultIterators.explain(planSteps);
- planSteps.add(" SERVER" + (limit == -1 ? "" : " TOP " + limit + " ROW" + (limit == 1 ? "" : "S")) + " SORTED BY " + orderByColumns.toString());
planSteps.add("CLIENT MERGE SORT");
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
index 2dfa573..2268866 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
@@ -24,6 +24,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
@@ -45,13 +46,14 @@ import org.apache.phoenix.filter.SkipScanFilter;
import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.KeyRange.Bound;
import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.PName;
import org.apache.phoenix.schema.PNameFactory;
-import org.apache.phoenix.schema.types.PVarbinary;
import org.apache.phoenix.schema.RowKeySchema;
import org.apache.phoenix.schema.ValueSchema.Field;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarbinary;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
/**
@@ -643,4 +645,17 @@ public class ScanUtil {
}
return tenantId;
}
+
+ public static Iterator<Filter> getFilterIterator(Scan scan) {
+ Iterator<Filter> filterIterator;
+ Filter topLevelFilter = scan.getFilter();
+ if (topLevelFilter == null) {
+ filterIterator = Iterators.emptyIterator();
+ } else if (topLevelFilter instanceof FilterList) {
+ filterIterator = ((FilterList) topLevelFilter).getFilters().iterator();
+ } else {
+ filterIterator = Iterators.singletonIterator(topLevelFilter);
+ }
+ return filterIterator;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/c823be99/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
index 7ad3e25..2f8088d 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
@@ -207,13 +207,11 @@ public class QueryPlanTest extends BaseConnectionlessQueryTest {
String query = "EXPLAIN SELECT * FROM TENANT_VIEW LIMIT 1";
ResultSet rs = conn.createStatement().executeQuery(query);
assertEquals("CLIENT SERIAL 1-WAY RANGE SCAN OVER BASE_MULTI_TENANT_TABLE ['tenantId']\n" +
- " SERVER FILTER BY PageFilter 1\n" +
" SERVER 1 ROW LIMIT\n" +
"CLIENT 1 ROW LIMIT", QueryUtil.getExplainPlan(rs));
query = "EXPLAIN SELECT * FROM TENANT_VIEW LIMIT " + Integer.MAX_VALUE;
rs = conn.createStatement().executeQuery(query);
assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER BASE_MULTI_TENANT_TABLE ['tenantId']\n" +
- " SERVER FILTER BY PageFilter " + Integer.MAX_VALUE + "\n" +
" SERVER " + Integer.MAX_VALUE + " ROW LIMIT\n" +
"CLIENT " + Integer.MAX_VALUE + " ROW LIMIT", QueryUtil.getExplainPlan(rs));
query = "EXPLAIN SELECT * FROM TENANT_VIEW WHERE username = 'Joe' LIMIT 1";