Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.9k
[feature](statistics) Statistics derivation.Step 1:ScanNode implement…#8947
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -53,6 +53,7 @@ | ||
| import org.apache.doris.qe.ConnectContext; | ||
| import org.apache.doris.qe.SessionVariable; | ||
| import org.apache.doris.resource.Tag; | ||
| import org.apache.doris.statistics.StatsRecursiveDerive; | ||
| import org.apache.doris.system.Backend; | ||
| import org.apache.doris.thrift.TExplainLevel; | ||
| import org.apache.doris.thrift.TNetworkAddress; | ||
| @@ -146,7 +147,7 @@ public class OlapScanNode extends ScanNode { | ||
| // Constructs node to scan given data files of table 'tbl'. | ||
| public OlapScanNode(PlanNodeId id, TupleDescriptor desc, String planNodeName) { | ||
| super(id, desc, planNodeName); | ||
| super(id, desc, planNodeName, NodeType.OLAP_SCAN_NODE); | ||
| olapTable = (OlapTable) desc.getTable(); | ||
| } | ||
| @@ -346,10 +347,25 @@ public void init(Analyzer analyzer) throws UserException { | ||
| * - So only an inaccurate cardinality can be calculated here. | ||
| */ | ||
| if (analyzer.safeIsEnableJoinReorderBasedCost()) { | ||
| mockRowCountInStatistic(); | ||
| computeInaccurateCardinality(); | ||
| } | ||
| } | ||
| /** | ||
| * Remove the method after statistics collection is working properly | ||
| */ | ||
| public void mockRowCountInStatistic() { | ||
| long tableId = desc.getTable().getId(); | ||
| cardinality = 0; | ||
| for (long selectedPartitionId : selectedPartitionIds) { | ||
| final Partition partition = olapTable.getPartition(selectedPartitionId); | ||
| final MaterializedIndex baseIndex = partition.getBaseIndex(); | ||
| cardinality += baseIndex.getRowCount(); | ||
| } | ||
| Catalog.getCurrentCatalog().getStatisticsManager().getStatistics().mockTableStatsWithRowCount(tableId, cardinality); | ||
| } | ||
| @Override | ||
| public void finalize(Analyzer analyzer) throws UserException { | ||
| LOG.debug("OlapScanNode get scan range locations. Tuple: {}", desc); | ||
| @@ -386,6 +402,12 @@ public void computeStats(Analyzer analyzer) { | ||
| } | ||
| // when node scan has no data, cardinality should be 0 instead of a invalid value after computeStats() | ||
| cardinality = cardinality == -1 ? 0 : cardinality; | ||
| // update statsDeriveResult for real statistics | ||
| // After statistics collection is complete, remove the logic | ||
| if (analyzer.safeIsEnableJoinReorderBasedCost()) { | ||
| statsDeriveResult.setRowCount(cardinality); | ||
EmmyMiao87 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| @Override | ||
| @@ -397,30 +419,9 @@ protected void computeNumNodes() { | ||
| numNodes = numNodes <= 0 ? 1 : numNodes; | ||
| } | ||
| /** | ||
| * Calculate inaccurate cardinality. | ||
| * cardinality: the value of cardinality is the sum of rowcount which belongs to selectedPartitionIds | ||
| * The cardinality here is actually inaccurate, it will be greater than the actual value. | ||
| * There are two reasons | ||
| * 1. During the actual execution, not all tablets belonging to the selected partition will be scanned. | ||
| * Some tablets may have been pruned before execution. | ||
| * 2. The base index may eventually be replaced by mv index. | ||
| * <p> | ||
| * There are three steps to calculate cardinality | ||
| * 1. Calculate how many rows were scanned | ||
| * 2. Apply conjunct | ||
| * 3. Apply limit | ||
| */ | ||
| private void computeInaccurateCardinality() { | ||
| // step1: Calculate how many rows were scanned | ||
| cardinality = 0; | ||
| for (long selectedPartitionId : selectedPartitionIds) { | ||
| final Partition partition = olapTable.getPartition(selectedPartitionId); | ||
| final MaterializedIndex baseIndex = partition.getBaseIndex(); | ||
| cardinality += baseIndex.getRowCount(); | ||
| } | ||
| applyConjunctsSelectivity(); | ||
| capCardinalityAtLimit(); | ||
| private void computeInaccurateCardinality() throws UserException { | ||
| StatsRecursiveDerive.getStatsRecursiveDerive().statsRecursiveDerive(this); | ||
| cardinality = statsDeriveResult.getRowCount(); | ||
| } | ||
| private Collection<Long> partitionPrune(PartitionInfo partitionInfo, PartitionNames partitionNames) throws AnalysisException { | ||
| @@ -563,7 +564,7 @@ private void addScanRangeLocations(Partition partition, | ||
| result.add(scanRangeLocations); | ||
| } | ||
| // FIXME(dhc): we use cardinality here to simulate ndv | ||
| if (tablets.size() == 0) { | ||
| desc.setCardinality(0); | ||
| } else { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -36,6 +36,7 @@ | ||
| import org.apache.doris.common.TreeNode; | ||
| import org.apache.doris.common.UserException; | ||
| import org.apache.doris.common.util.VectorizedUtil; | ||
| import org.apache.doris.statistics.StatsDeriveResult; | ||
| import org.apache.doris.thrift.TExplainLevel; | ||
| import org.apache.doris.thrift.TFunctionBinaryType; | ||
| import org.apache.doris.thrift.TPlan; | ||
| @@ -135,6 +136,9 @@ abstract public class PlanNode extends TreeNode<PlanNode> { | ||
| protected List<SlotId> outputSlotIds; | ||
| protected NodeType nodeType = NodeType.DEFAULT; | ||
| protected StatsDeriveResult statsDeriveResult; | ||
| protected PlanNode(PlanNodeId id, ArrayList<TupleId> tupleIds, String planNodeName) { | ||
EmmyMiao87 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| this.id = id; | ||
| this.limit = -1; | ||
| @@ -173,12 +177,41 @@ protected PlanNode(PlanNodeId id, PlanNode node, String planNodeName) { | ||
| this.planNodeName = VectorizedUtil.isVectorized() ? | ||
| "V" + planNodeName : planNodeName; | ||
| this.numInstances = 1; | ||
| this.nodeType = nodeType; | ||
| } | ||
| public enum NodeType { | ||
| DEFAULT, | ||
| AGG_NODE, | ||
| BROKER_SCAN_NODE, | ||
| HASH_JOIN_NODE, | ||
| HIVE_SCAN_NODE, | ||
| MERGE_NODE, | ||
| ES_SCAN_NODE, | ||
| ICEBREG_SCAN_NODE, | ||
| LOAD_SCAN_NODE, | ||
| MYSQL_SCAN_NODE, | ||
| ODBC_SCAN_NODE, | ||
| OLAP_SCAN_NODE, | ||
| SCHEMA_SCAN_NODE, | ||
| } | ||
| public String getPlanNodeName() { | ||
| return planNodeName; | ||
| } | ||
| public StatsDeriveResult getStatsDeriveResult() { | ||
| return statsDeriveResult; | ||
| } | ||
| public NodeType getNodeType() { | ||
| return nodeType; | ||
| } | ||
| public void setStatsDeriveResult(StatsDeriveResult statsDeriveResult) { | ||
| this.statsDeriveResult = statsDeriveResult; | ||
| } | ||
| /** | ||
| * Sets tblRefIds_, tupleIds_, and nullableTupleIds_. | ||
| * The default implementation is a no-op. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -65,8 +65,9 @@ abstract public class ScanNode extends PlanNode { | ||
| protected String sortColumn = null; | ||
| protected Analyzer analyzer; | ||
| public ScanNode(PlanNodeId id, TupleDescriptor desc, String planNodeName) { | ||
| public ScanNode(PlanNodeId id, TupleDescriptor desc, String planNodeName, NodeType nodeType) { | ||
| super(id, desc.getId().asList(), planNodeName); | ||
EmmyMiao87 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| super.nodeType = nodeType; | ||
| this.desc = desc; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.