Oracle De-supports Rule-based SQL Optimizer
Oracle Tips by Burleson Consulting
Oracle has announced that with Oracle 11g, the rule-based
optimizer (RBO) will no longer be supported, and you need to
move quickly to migrate to the cost-based optimizer (CBO).
OPTIMIZER_MODE=RULE is not supported in Oracle Database
11g; the code has only been left in Oracle to enable easy
migrations from RBO to CBO. We do not recommended you use
OPTIMIZER_MODE=RULE as a long term strategy in Oracle
Database 11g as the code can be removed at any time now that it
Migrating to the cost-based optimizer is tricky and
dangerous, and you need to hire experts who have experience doing an
RBO to CBO migration.
Don't risk an unplanned outage.
For those experienced DBA's who wish to
migrate away from rule-based optimization, here are some tips.
With a large number of Oracle shops
using the rule-based optimizer (RBO), migration to cost-based
optimization (CBO) will become a important task when migrating to Oracle11g, where the RBO will disappear.
As you may know, Oracle provides several
parameters that can adjust the behavior of the CBO to make it more like
Today we examine optimizer_index_caching, and
we will cover the other parameters in later tips.
Important Note: Prior to Oracle 10g, adjusting these optimizer parameters
was the only way to compensate for sample size issues with dbms_stats.
As of 10g, the use of dbms_stats.gather_system_stats and improved
sampling within dbms_stats had made adjustments to these parameters far
less important. Ceteris Parabus, always adjust CBO statistics before adjusting
optimizer parms. For more details on optimizer parameters, see my latest book "Oracle
Tuning: The Definitive Reference".
This is the most important parameter of
all, and the default setting of 100 is incorrect for most Oracle
systems. For some OLTP systems, re-setting this parameter to a
smaller value (between 10- to 30) may result in huge performance
If you are having
slow performance because the CBO first_rows optimizer mode is
favoring too many full-table scans, you can reduce the value of the
optimizer_index_cost_adj parameter to immediately tune all of the
SQL in your database to favor index scans over full-table scans.
This is sometimes a "silver bullet" that can improve the performance
of an entire database in cases where the database is OLTP and you
have verified that the full-table scan costing is too low.
Even in Oracle, the CBO sometimes
falsely determines that the cost of full-table scan is less than the
cost of an index access. The optimizer_index_cost_adj parameter
is a great approach to whole-system SQL tuning, but you will need to
evaluate the overall effect by slowly resetting the value down from
100 and observing the percentage of full-tale scans. You can also
slowly bump down the value of optimizer_index_cost_adj when you
bounce the database and then either use the access.sql or
plan.sql scripts or reexamine SQL from the STATSPACK
stats$sql_summary table to see the net effect of index scans on
the whole database.
script (see code depot
from book below) uses the v$sql_plan
view and a quickly the reduction in sub-optimal, large-table
Full table scans and counts
Note that "K"
indicates in the table is in the KEEP pool.
NUM_ROWS C K BLOCKS NBR_FTS
-------------- ------------------------ --------- - -
N K 2 16,178
PAGE 3,450,209 N 932,120
434 N 8
18,067 N 1,104 5,368
476 N K 192
10 N K 32
The optimizer_index_caching parameter
The optimizer_index_caching parameter is
a percentage parameter with valid values between zero and 100. This
parameter lets you adjust the behavior of the cost-based optimizer to
select nested loop joins more often or less often. The cost of executing
a nested loop join where an index is used to access the inner table is
highly dependent on the caching of that index in the buffer cache. The
amount of index caching depends on factors, such as the load on the
system and the block access patterns of different users, that the
optimizer cannot predict. Of course, you may cache an index by placing
the data block in the KEEP pool, thereby ensuring that the blocks are
Setting optimizer_index_caching to a
higher percentage makes nested loop joins look less expensive to the
optimizer, which will be more likely to pick nested loop joins over hash
or sort merge joins.
The default value for the
optimizer_index_caching parameter is 0, which gives the highest
preference to hash joins and sort merge joins. Resetting this parameter
can be very dangerous if you are not using stored outlines because it
could change the execution plans for thousands of SQL statements. Also,
because the cost-based optimizer will generally only invoke sort merge
joins when there are no indexes on the joined tables, this parameter has
the most effect on the invocation of hash joins.
According to Oracle, selective indexes are favored by
optimizier_index_caching. The result of using lower values
for this parameter will be the optimizer effectively modeling the caches
of non-leaf index blocks.
For this situation, the cost of using this index will be based mostly on
its selectivity. Using a lower valuse of
optimizer_index_caching will result in an index caching model that
is less likely to overuse potentially lesser desirable indexes with
Even though Oracle has deprecated the rule-based
optimizer, Oracle continues to use the rule hint in Oracle 11g, as shown by
this Data Pump internal SQL:
Module: Data Pump Worker
KU$.OBJ_NUM ,KU$.ANC_OBJ.NAME . . .
More information is available on the
Get the Complete
Oracle SQL Tuning Information
The landmark book
SQL Tuning The Definitive Reference" is
filled with valuable information on Oracle SQL Tuning.
This book includes scripts and tools to hypercharge Oracle 11g
performance and you can
for 30% off directly from the publisher.