diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/cost/HiveCost.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/cost/HiveCost.java index f9f3d0c..34a37e4 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/cost/HiveCost.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/cost/HiveCost.java @@ -8,7 +8,7 @@ public class HiveCost implements RelOptCost { // ~ Static fields/initializers --------------------------------------------- - static final HiveCost INFINITY = new HiveCost(Double.POSITIVE_INFINITY, + public static final HiveCost INFINITY = new HiveCost(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY) { @Override @@ -17,7 +17,7 @@ public String toString() { } }; - static final HiveCost HUGE = new HiveCost(Double.MAX_VALUE, Double.MAX_VALUE, + public static final HiveCost HUGE = new HiveCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE) { @Override public String toString() { @@ -25,14 +25,14 @@ public String toString() { } }; - static final HiveCost ZERO = new HiveCost(0.0, 0.0, 0.0) { + public static final HiveCost ZERO = new HiveCost(0.0, 0.0, 0.0) { @Override public String toString() { return "{0}"; } }; - static final HiveCost TINY = new HiveCost(1.0, 1.0, 0.0) { + public static final HiveCost TINY = new HiveCost(1.0, 1.0, 0.0) { @Override public String toString() { return "{tiny}"; diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/reloperators/HiveJoinRel.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/reloperators/HiveJoinRel.java index fa73abf..01588c2 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/reloperators/HiveJoinRel.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/reloperators/HiveJoinRel.java @@ -7,12 +7,13 @@ import java.util.Set; import org.apache.hadoop.hive.ql.optimizer.optiq.TraitsUtil; -import org.apache.hadoop.hive.ql.optimizer.optiq.cost.HiveCostUtil; +import org.apache.hadoop.hive.ql.optimizer.optiq.cost.HiveCost; import org.eigenbase.rel.InvalidRelException; import org.eigenbase.rel.JoinRelBase; import org.eigenbase.rel.JoinRelType; import org.eigenbase.rel.RelFactories.JoinFactory; import org.eigenbase.rel.RelNode; +import org.eigenbase.rel.metadata.RelMetadataQuery; import org.eigenbase.relopt.RelOptCluster; import org.eigenbase.relopt.RelOptCost; import org.eigenbase.relopt.RelOptPlanner; @@ -108,10 +109,15 @@ public boolean isLeftSemiJoin() { return m_leftSemiJoin; } + /** + * Model cost of join as size of Inputs. + */ @Override public RelOptCost computeSelfCost(RelOptPlanner planner) { - return HiveCostUtil.computCardinalityBasedCost(this); - } + double leftRCount = RelMetadataQuery.getRowCount(getLeft()); + double rightRCount = RelMetadataQuery.getRowCount(getRight()); + return HiveCost.FACTORY.makeCost(leftRCount + rightRCount, 0.0, 0.0); + } /** * @return returns rowtype representing only the left join input diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/HiveRelMdDistinctRowCount.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/HiveRelMdDistinctRowCount.java index f8d946b..8e36d20 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/HiveRelMdDistinctRowCount.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/HiveRelMdDistinctRowCount.java @@ -6,24 +6,36 @@ import net.hydromatic.optiq.BuiltinMethod; import org.apache.hadoop.hive.ql.optimizer.optiq.HiveOptiqUtil; +import org.apache.hadoop.hive.ql.optimizer.optiq.cost.HiveCost; import org.apache.hadoop.hive.ql.optimizer.optiq.reloperators.HiveJoinRel; import org.apache.hadoop.hive.ql.optimizer.optiq.reloperators.HiveTableScanRel; import org.apache.hadoop.hive.ql.plan.ColStatistics; import org.eigenbase.rel.JoinRelBase; import org.eigenbase.rel.RelNode; +import org.eigenbase.rel.metadata.ChainedRelMetadataProvider; import org.eigenbase.rel.metadata.ReflectiveRelMetadataProvider; import org.eigenbase.rel.metadata.RelMdDistinctRowCount; import org.eigenbase.rel.metadata.RelMdUtil; import org.eigenbase.rel.metadata.RelMetadataProvider; import org.eigenbase.rel.metadata.RelMetadataQuery; +import org.eigenbase.relopt.RelOptCost; import org.eigenbase.rex.RexNode; -import org.eigenbase.util14.NumberUtil; + +import com.google.common.collect.ImmutableList; public class HiveRelMdDistinctRowCount extends RelMdDistinctRowCount { - public static final RelMetadataProvider SOURCE = ReflectiveRelMetadataProvider - .reflectiveSource( - BuiltinMethod.DISTINCT_ROW_COUNT.method, - new HiveRelMdDistinctRowCount()); + + private static final HiveRelMdDistinctRowCount INSTANCE = + new HiveRelMdDistinctRowCount(); + + public static final RelMetadataProvider SOURCE = ChainedRelMetadataProvider + .of(ImmutableList.of( + + ReflectiveRelMetadataProvider.reflectiveSource( + BuiltinMethod.DISTINCT_ROW_COUNT.method, INSTANCE), + + ReflectiveRelMetadataProvider.reflectiveSource( + BuiltinMethod.CUMULATIVE_COST.method, INSTANCE))); private HiveRelMdDistinctRowCount() { } @@ -35,9 +47,11 @@ public Double getDistinctRowCount(RelNode rel, BitSet groupKey, if (rel instanceof HiveTableScanRel) { return getDistinctRowCount((HiveTableScanRel) rel, groupKey, predicate); } - - return NumberUtil.multiply(RelMetadataQuery.getRowCount(rel), - RelMetadataQuery.getSelectivity(rel, predicate)); + /* + * For now use Optiq' default formulas for propagating NDVs up the Query + * Tree. + */ + return super.getDistinctRowCount(rel, groupKey, predicate); } private Double getDistinctRowCount(HiveTableScanRel htRel, BitSet groupKey, @@ -77,4 +91,20 @@ public Double getDistinctRowCount(JoinRelBase rel, BitSet groupKey, return RelMetadataQuery.getDistinctRowCount(rel, groupKey, predicate); } + + /* + * Favor Broad Plans over Deep Plans. + */ + public RelOptCost getCumulativeCost(HiveJoinRel rel) { + RelOptCost cost = RelMetadataQuery.getNonCumulativeCost(rel); + List inputs = rel.getInputs(); + RelOptCost maxICost = HiveCost.ZERO; + for (RelNode input : inputs) { + RelOptCost iCost = RelMetadataQuery.getCumulativeCost(input); + if (maxICost.isLt(iCost)) { + maxICost = iCost; + } + } + return cost.plus(maxICost); + } }