DbGroupScan dbGroupScan = (DbGroupScan) primaryTableGroupScan; DrillCostFactory costFactory = (DrillCostFactory)planner.getCostFactory(); double totalRows = indexProps.getTotalRows(); double leadRowCount = indexProps.getLeadingSelectivity() * totalRows; double avgRowSize = indexProps.getAvgRowSize(); if (indexProps.isCovering()) { // covering index if (indexProps.getTotalRemainderFilter() != null) { cpuCost = leadRowCount * DrillCostBase.COMPARE_CPU_COST; if (indexProps.getTotalRemainderFilter() != null) { cpuCost = leadRowCount * DrillCostBase.COMPARE_CPU_COST;
final List<RexNode> remFilterList = Lists.newArrayList(); for (IndexProperties indexProps : index.getIndexProps()) { remFilterList.add(indexProps.getTotalRemainderFilter()); totalRows = indexProps.getTotalRows(); double leadRowCount = indexProps.getLeadingSelectivity() * indexProps.getRemainderSelectivity() * totalRows; totLeadRowCount *= indexProps.getLeadingSelectivity(); double avgRowSize = indexProps.getAvgRowSize(); Preconditions.checkArgument(primaryTableGroupScan instanceof DbGroupScan); rightSideRows = leadRowCount; remFilters = remainderCondition(indexProps.getIndexDesc(), builder, remFilters);
o1Covering = o1.get(0).isCovering(); o1NumLeadingFilters = o1.get(0).numLeadingFilters(); o1SatisfiesCollation = o1.get(0).satisfiesCollation(); o1LeadingSelectivity = o1.get(0).getLeadingSelectivity(); } else { o1Covering = false; o1NumLeadingFilters = o1.get(0).numLeadingFilters(); for (int idx=1; idx<o1.size(); idx++) { o1NumLeadingFilters+=o1.get(idx).numLeadingFilters(); o1LeadingSelectivity = o1.get(0).getLeadingSelectivity(); for (int idx=1; idx<o1.size(); idx++) { o1LeadingSelectivity*=o1.get(idx).getLeadingSelectivity(); o2Covering = o2.get(0).isCovering(); o2NumLeadingFilters = o2.get(0).numLeadingFilters(); o2SatisfiesCollation = o2.get(0).satisfiesCollation(); o2LeadingSelectivity = o2.get(0).getLeadingSelectivity(); } else { o2Covering = false; o2NumLeadingFilters = o2.get(0).numLeadingFilters(); for (int idx=1; idx<o2.size(); idx++) { o2NumLeadingFilters+=o2.get(idx).numLeadingFilters(); o2LeadingSelectivity = o2.get(0).getLeadingSelectivity(); for (int idx=1; idx<o2.size(); idx++) { o2LeadingSelectivity*=o2.get(idx).getLeadingSelectivity();
if (candidateIndexes.get(idx).getIndexProps().get(0).isCovering()) { continue; candidateDescs.add(prop.getIndexDesc()); candidateDescs.add(candidateIndexes.get(idx).getIndexProps().get(0).getIndexDesc()); Map<IndexDescriptor, IndexConditionInfo> intersectIdxInfoMap = infoBuilder.getIndexConditionMap(candidateDescs); if (indexesInCandidate.isIntersectIndex()) { for (IndexProperties prop : indexesInCandidate.getIndexProps()) { currSel *= prop.getLeadingSelectivity();
strb.append("Covering indexes:"); for (IndexGroup index : coveringIndexes) { strb.append(index.getIndexProps().get(0).getIndexDesc().getIndexName()).append(", "); strb.append("Non-covering indexes:"); for (IndexGroup index : nonCoveringIndexes) { strb.append(index.getIndexProps().get(0).getIndexDesc().getIndexName()).append(", "); List<IndexDescriptor> indexList = Lists.newArrayList(); for (IndexGroup index : nonCoveringIndexes) { IndexDescriptor indexDesc = index.getIndexProps().get(0).getIndexDesc(); IndexGroupScan idxScan = indexDesc.getIndexGroupScan(); indexList.add(index.getIndexProps().get(0).getIndexDesc()); List<String> indices = new ArrayList<>(nonCoveringIndexes.size()); for (IndexGroup index : nonCoveringIndexes) { indices.add(index.getIndexProps().get(0).getIndexDesc().getIndexName()); List<IndexDescriptor> candidateDesc = Lists.newArrayList(); for (IndexProperties candProp : index.getIndexProps()) { candidateDesc.add(candProp.getIndexDesc()); for (IndexGroup index : coveringIndexes) { IndexProperties indexProps = index.getIndexProps().get(0); IndexDescriptor indexDesc = indexProps.getIndexDesc(); IndexGroupScan idxScan = indexDesc.getIndexGroupScan(); FunctionalIndexInfo indexInfo = indexDesc.getFunctionalInfo();
/** * This method analyzes an index's columns and starting from the first column, checks * which part of the filter condition matches that column. This process continues with * subsequent columns. The goal is to identify the portion of the filter condition that * match the prefix columns. If there are additional conditions that don't match prefix * columns, that condition is set as a remainder condition. * @param indexProps */ public void analyzePrefixMatches(IndexProperties indexProps) { RexNode initCondition = indexCondition.isAlwaysTrue() ? null : indexCondition; Map<LogicalExpression, RexNode> leadingPrefixMap = Maps.newHashMap(); List<LogicalExpression> indexCols = indexProps.getIndexDesc().getIndexColumns(); boolean satisfiesCollation = false; if (indexCols.size() > 0) { if (initCondition != null) { // check filter condition initCondition = IndexPlanUtils.getLeadingPrefixMap(leadingPrefixMap, indexCols, builder, indexCondition); } if (requiredCollation()) { satisfiesCollation = buildAndCheckCollation(indexProps); } } indexProps.setProperties(leadingPrefixMap, satisfiesCollation, initCondition /* the remainder condition for indexed columns */, stats); }
new CoveringPlanNoFilterGenerator(indexContext, idxProp.getIndexDesc().getFunctionalInfo(), false, settings); if (planGen.convertChild() != null) {
if (p.numLeadingFilters() > 0 || p.satisfiesCollation()) { double selThreshold = p.isCovering() ? settings.getIndexCoveringSelThreshold() : settings.getIndexNonCoveringSelThreshold(); if (settings.isDisableFullTableScan() || p.getLeadingSelectivity() <= selThreshold) { IndexGroup index = new IndexGroup(); index.addIndexProp(p); if (p.getLeadingSelectivity() > selThreshold) { logger.debug("Skipping index {}. The leading selectivity {} is larger than threshold {}", p.getIndexDesc().getIndexName(), p.getLeadingSelectivity(), selThreshold); IndexGroup index = candidateIndexes.get(i); if (index.numIndexes() == 1 && index.getIndexProps().get(0).isCovering()) { IndexProperties indexProps = index.getIndexProps().get(0); if (foundCoveringCollation) { logger.debug("index_plan_info: Skipping covering index {} because a higher ranked covering index with collation already exists.", indexProps.getIndexDesc().getIndexName()); continue; indexProps.getIndexDesc().getIndexName(), indexProps.satisfiesCollation(), indexProps.getLeadingSelectivity(), indexProps.getSelfCost(planner)); count++; foundCovering = true; if (indexProps.satisfiesCollation()) { foundCoveringCollation = true;
private boolean buildAndCheckCollation(IndexProperties indexProps) { IndexDescriptor indexDesc = indexProps.getIndexDesc(); FunctionalIndexInfo functionInfo = indexDesc.getFunctionalInfo(); RelCollation inputCollation; // for the purpose of collation we can assume that a covering index scan would provide // the collation property that would be relevant for non-covering as well ScanPrel indexScanPrel = IndexPlanUtils.buildCoveringIndexScan(indexContext.getScan(), indexDesc.getIndexGroupScan(), indexContext, indexDesc); inputCollation = indexScanPrel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE); // we don't create collation for Filter because it will inherit the child's collation if (indexContext.hasLowerProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getLowerProject().getProjects(), null, indexContext.getScan(), functionInfo,indexContext); } if (indexContext.hasUpperProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getUpperProject().getProjects(), indexContext.getLowerProject(), indexContext.getScan(), functionInfo, indexContext); } if ((inputCollation != null) && (inputCollation.satisfies(indexContext.getCollation()))) { return true; } return false; }
DbGroupScan dbGroupScan = (DbGroupScan) primaryTableGroupScan; DrillCostFactory costFactory = (DrillCostFactory)planner.getCostFactory(); double totalRows = indexProps.getTotalRows(); double leadRowCount = indexProps.getLeadingSelectivity() * totalRows; double avgRowSize = indexProps.getAvgRowSize(); if (indexProps.isCovering()) { // covering index if (indexProps.getTotalRemainderFilter() != null) { cpuCost = leadRowCount * DrillCostBase.COMPARE_CPU_COST; if (indexProps.getTotalRemainderFilter() != null) { cpuCost = leadRowCount * DrillCostBase.COMPARE_CPU_COST;