PersonalityBasedCostEstimation
From Eigenpedia
This is a proposal for enhancing package org.eigenbase.relopt and related components to make costing personality-based.
Update 30-Mar-2006: this proposal has been rolled into RelationalExpressionMetadata rather than being added as the separate interface as described here.
Background
Currently (eigenchange 5985), the only way to get cost estimation for a rel is to call the computeSelfCost method on interface RelNode--that is, by asking the rel itself. This makes it impossible for different Eigenbase extensions to use different cost models for common rels such as FennelAggregateRel. Here are some reasons why this might be needed:
- Optimizers may need to extend the standard cost (CPU, I/O, rowcount) with additional attributes (e.g. network bandwidth).
- Even for standard attributes, optimizers may compute them in different ways (e.g. memory-sensitivity for I/O cost in FennelSortRel).
- Optimizers may have available external information such as historical information, allowing them to supply costs empirically via pattern matching with previously executed plans.
Of course, it's usually possible to "hack around" these by extending the set of rules and rels. For example, the history-driven optimizer could match a pattern and rewrite it to an equivalent structure of new rels with the cost "burned in". But this is cumbersome and likely to have unpleasant interactions with other rulesets.
Proposal
- Introduce new interface org.eigenbase.relopt.RelOptCostEstimator with method estimateCost(RelNode rel) returning RelOptCost. By making it a separate interface (rather than adding a new method to RelOptPlanner), we make it possible to mix and match cost models with planner implementations with minimal fuss.
- Add a reference to RelOptCostEstimator (as a data member, accessor method, and constructor parameter) to RelOptCluster.
- Change VolcanoPlanner (and anything else currently calling directly to rels) to call RelCostEstimator instead.
- Introduce new class org.eigenbase.relopt.DefaultCostEstimator which implements estimateCost by just calling rel.computeSelfCost (preserving the existing behavior).
- Introduce new class org.eigenbase.relopt.ReflectiveCostEstimator which implements estimateCost by dispatching to itself via ReflectUtil.invokeVisitor. Subclasses can then provide methods with specific rel arguments, e.g. ReflectiveCostEstimator.estimateCost(FennelAggregateRel rel) and these will be looked up via reflection. (Using reflection is necessary in order for the visitor pattern to work with plugins with their own rels.) This way an entire cost model can be written in a single estimator class if desired. Unhandled visit methods can be dispatched as for DefaultCostEstimator.
- Other patterns for constructing and combining estimators are possible, e.g. chaining.

