The Oracle cost-based optimizer displays
cost figures, but these are very misleading because a low cost
value does not always indicate the "real" lowest cost that is
select by the optimizer. In other words, Oracle does not
always choose the lowest "cost" value, and Oracle does not
disclose the exact behavior of their optimizer, a prized
competitive edge over other competing databases.
While Oracle does not publish the
internal machinations of their proprietary optimizer costing
model, many Oracle experts have reverse engineered the software
and developed equations for estimating the cost.
Warning about the
"cost" display:
It's important to note that the cost
figures that are displayed in an execution plan are not
described in any Oracle documentation, and it's been
demonstrated that the plan with the lowest "cost" number is not
always the plan chosen by the optimizer.
Further, the "cost" figures do not always indicate the
"best:" execution plan for a query, given the divergent
optimizer goals of first_rows (optimizer for response
time) and all_rows (optimize for minimizing computing
resources).
Given my warnings, there are many experts who have
attempted to reverse engineer the costing algorithms, with mixed
success.
Vivek Sharma has
this note where he described tuning a difficult query by
adjusting the optimizer_index_cost_adj parameter for a
specific user.
Sharma notes that the "best" action (changing the query with a
hint) was impossible because of code access limitations.
This limitation of "you cannot changed the SQL" is common with
seeded ad-hoc SQL or with vendor packages.
In this case, he used a login trigger to set
optimizer_index_cost_adj to a higher value, thereby
increasing the probability that the Oracle optimizer would
choose a full scan operation.
This Oracle 8i database, Mr. Sharma applies costing
equations for various execution plans. Here he notes the
costs of calculating index scan costs and table scan costs:
The Cost Calculation of an Index Scan and
Table Scan via Index is:
- Index Cost = Blevel+ceil(leaf_blocks*ix_selectivity)
- Table Scan cost = ceil(clustering_factor*table_selectivity)
- Nested loops Cost = Cost of an Outer Table +
(Cost of Inner Table * Cardinality of Outer Table)
- Nested Loops Table Scan Cost = (Current Cost
of Inner Table Scan * Outer Table Card)*OICA/100
Again, beware that Oracle does not publishing their costing
internals, and that the "cost" values in an execution plan are
misleading because they do not always reflect the "real" best
access plan for an SQL statement.