private double getIntervalCostMultiplier() { int days = 0; for (Interval interval : intervals) { days += interval.toDuration().getStandardDays(); } // Cost increases with the wider interval being queries. // A plan querying 10 or more years of data will have 10x the cost of a // plan returning 1 day data. // A plan where least interval is queries will be preferred. return RelMdUtil.linear(days, 1, DAYS_IN_TEN_YEARS, 0.1d, 1d); }
private double getIntervalCostMultiplier() { int days = 0; for (Interval interval : intervals) { days += interval.toDuration().getStandardDays(); } // Cost increases with the wider interval being queries. // A plan querying 10 or more years of data will have 10x the cost of a // plan returning 1 day data. // A plan where least interval is queries will be preferred. return RelMdUtil.linear(days, 1, DAYS_IN_TEN_YEARS, 0.1d, 1d); }
/** Unit test for {@link RelMdUtil#linear(int, int, int, double, double)}. */ @Test public void testLinear() { assertThat(RelMdUtil.linear(0, 0, 10, 100, 200), is(100d)); assertThat(RelMdUtil.linear(5, 0, 10, 100, 200), is(150d)); assertThat(RelMdUtil.linear(6, 0, 10, 100, 200), is(160d)); assertThat(RelMdUtil.linear(10, 0, 10, 100, 200), is(200d)); assertThat(RelMdUtil.linear(-2, 0, 10, 100, 200), is(100d)); assertThat(RelMdUtil.linear(12, 0, 10, 100, 200), is(200d)); }
/** Unit test for {@link RelMdUtil#linear(int, int, int, double, double)}. */ @Test public void testLinear() { assertThat(RelMdUtil.linear(0, 0, 10, 100, 200), is(100d)); assertThat(RelMdUtil.linear(5, 0, 10, 100, 200), is(150d)); assertThat(RelMdUtil.linear(6, 0, 10, 100, 200), is(160d)); assertThat(RelMdUtil.linear(10, 0, 10, 100, 200), is(200d)); assertThat(RelMdUtil.linear(-2, 0, 10, 100, 200), is(100d)); assertThat(RelMdUtil.linear(12, 0, 10, 100, 200), is(200d)); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { return Util.last(rels) .computeSelfCost(planner, mq) // Cost increases with the number of fields queried. // A plan returning 100 or more columns will have 2x the cost of a // plan returning 2 columns. // A plan where all extra columns are pruned will be preferred. .multiplyBy( RelMdUtil.linear(querySpec.fieldNames.size(), 2, 100, 1d, 2d)) .multiplyBy(getQueryTypeCostMultiplier()) // A Scan leaf filter is better than having filter spec if possible. .multiplyBy(rels.size() > 1 && rels.get(1) instanceof Filter ? 0.5 : 1.0) // a plan with sort pushed to druid is better than doing sort outside of druid .multiplyBy(Util.last(rels) instanceof Sort ? 0.1 : 1.0) .multiplyBy(getIntervalCostMultiplier()); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { return Util.last(rels) .computeSelfCost(planner, mq) // Cost increases with the number of fields queried. // A plan returning 100 or more columns will have 2x the cost of a // plan returning 2 columns. // A plan where all extra columns are pruned will be preferred. .multiplyBy( RelMdUtil.linear(querySpec.fieldNames.size(), 2, 100, 1d, 2d)) .multiplyBy(getQueryTypeCostMultiplier()) // a plan with sort pushed to druid is better than doing sort outside of druid .multiplyBy(Util.last(rels) instanceof Sort ? 0.1 : 1.0) .multiplyBy(getIntervalCostMultiplier()); }