Skip to Main Content
  • Questions
  • rule based optimizer used (consider using cbo)

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Duke.

Asked: August 20, 2008 - 12:24 pm UTC

Last updated: April 24, 2013 - 12:45 pm UTC

Version: 10.2.0.3.0

Viewed 1000+ times

You Asked

When I look at an explain plan and see
"rule based optimizer used (consider using cbo)"
How do I track down the reason for the RBO being used, and change it so the CBO is used?

and Tom said...

either

a) the database optimizer mode is set wrong, should be all_rows in 10g, when set to all_rows, you will always be using the CBO.

b) the query contains a rule hint - you would see it

c) the session was altered to use the rbo


those are the only three times I can think of. (b) is most likely, (c) is second most likely. If it is (c), you have to track down the code that executed that sql and fix it.

Rating

  (9 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Alexander, August 21, 2008 - 12:50 pm UTC

How about no optimizer stats on the objects?
Tom Kyte
August 21, 2008 - 10:09 pm UTC

if the optimizer mode is set right (this is 10.2.0.3 remember), it will be using the CBO regardless, the default and correct setting is ALL_ROWS.

so, (a) covered that.

CBO v RBO

Duke Ganote, August 22, 2008 - 6:59 am UTC

SQL*Plus: Release 10.2.0.1.0 - Production on Fri Aug 22 06:29:42 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options


Session altered.

Elapsed: 00:00:00.08

Session altered.

Elapsed: 00:00:00.08
whse2000:prot\ciopdba> ed glogin.sql -- SHOWN AT BOTTOM

whse2000:prot\ciopdba> set autot on exp;
whse2000:prot\ciopdba> select count(*) from o_prdcr_prod_wip;

            COUNT(*)
--------------------
           9,635,613

Elapsed: 00:00:49.49

Execution Plan
----------------------------------------------------------
Plan hash value: 2446809081

-----------------------------------------------
| Id  | Operation          | Name             |
-----------------------------------------------
|   0 | SELECT STATEMENT   |                  |
|   1 |  SORT AGGREGATE    |                  |
|   2 |   TABLE ACCESS FULL| O_PRDCR_PROD_WIP |
-----------------------------------------------

Note
-----
   - rule based optimizer used (consider using cbo)

whse2000:prot\ciopdba> select count(*) from object_timing;

            COUNT(*)
--------------------
              24,630

Elapsed: 00:00:00.11

Execution Plan
----------------------------------------------------------
Plan hash value: 3904142253

----------------------------------------------------------------------------
| Id  | Operation          | Name          | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |               |     1 |    36   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |               |     1 |            |          |
|   2 |   TABLE ACCESS FULL| OBJECT_TIMING | 22350 |    36   (0)| 00:00:01 |
----------------------------------------------------------------------------

whse2000:prot\ciopdba>

***************************************************
***************************************************
--
-- Copyright (c) 1988, 2004, Oracle Corporation.  All Rights Reserved.
--
-- NAME
--   glogin.sql
--
-- DESCRIPTION
--   SQL*Plus global login "site profile" file
--
--   Add any SQL*Plus commands here that are to be executed when a
--   user starts SQL*Plus, or uses the SQL*Plus CONNECT command
--
-- USAGE
--   This script is automatically run
--

-- Used by Trusted Oracle
COLUMN ROWLABEL FORMAT A15

-- Used for the SHOW ERRORS command
COLUMN LINE/COL FORMAT A8
COLUMN ERROR    FORMAT A65  WORD_WRAPPED

-- Used for the SHOW SGA command
COLUMN name_col_plus_show_sga FORMAT a24
COLUMN units_col_plus_show_sga FORMAT a15
-- Defaults for SHOW PARAMETERS
COLUMN name_col_plus_show_param FORMAT a36 HEADING NAME
COLUMN value_col_plus_show_param FORMAT a30 HEADING VALUE

-- Defaults for SHOW RECYCLEBIN
COLUMN origname_plus_show_recyc   FORMAT a16 HEADING 'ORIGINAL NAME'
COLUMN objectname_plus_show_recyc FORMAT a30 HEADING 'RECYCLEBIN NAME'
COLUMN objtype_plus_show_recyc    FORMAT a12 HEADING 'OBJECT TYPE'
COLUMN droptime_plus_show_recyc   FORMAT a19 HEADING 'DROP TIME'

-- Defaults for SET AUTOTRACE EXPLAIN report
-- These column definitions are only used when SQL*Plus
-- is connected to Oracle 9.2 or earlier.
COLUMN id_plus_exp FORMAT 990 HEADING i
COLUMN parent_id_plus_exp FORMAT 990 HEADING p
COLUMN plan_plus_exp FORMAT a60
COLUMN object_node_plus_exp FORMAT a8
COLUMN other_tag_plus_exp FORMAT a29
COLUMN other_plus_exp FORMAT a44

-- Default for XQUERY
COLUMN result_plus_xquery HEADING 'Result Sequence'

-- Duke's magic
column COUNT(*) format 999,999,999,999,999;
column CNT format 999,999,999,999,999;
SET SERVEROUTPUT ON;
set timing on;
set pagesize 50000;
set linesize 132;
set termout off;
DEFINE sqlprompt=SQL;
COLUMN sqlprompt NEW_VALUE sqlprompt;
SELECT LOWER(SYS_CONTEXT('USERENV','CURRENT_USER'))
    as sqlprompt 
  from dual
;
SELECT SYS_CONTEXT('USERENV','SERVER_HOST')
       ||':'
       || SYS_CONTEXT('USERENV','DB_NAME')
       ||'\'
       || LOWER(SYS_CONTEXT('USERENV','CURRENT_USER'))
    as sqlprompt 
  from dual
;
set termout on;
set sqlprompt '&sqlprompt> ';
alter session set nls_date_format='yyyy-mm-dd HH24:MI:SS';
alter session set nls_timestamp_format = 'yyyy-mm-dd HH24:MI:SS.FF';

Tom Kyte
August 22, 2008 - 9:52 am UTC

what is your OPTIMIZER set to - that is the question, show parameter optimizer

it looks like "choose", not ALL_ROWS which is should be. If it were all rows, it would use the CBO

That's it! I did not "choose wisely"...

Duke Ganote, August 22, 2008 - 10:00 am UTC

SQL> alter session set optimizer_mode = all_rows;

Session altered.

SQL> set autot on exp;
SQL> select count(*) from ciopdba.o_prdcr_prod_wip;

            COUNT(*)
--------------------
           9,635,613

Elapsed: 00:00:02.06

Execution Plan
----------------------------------------------------------
Plan hash value: 2446809081

-------------------------------------------------------------------------------
| Id  | Operation          | Name             | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                  |     1 |  7418   (3)| 00:01:30 |
|   1 |  SORT AGGREGATE    |                  |     1 |            |          |
|   2 |   TABLE ACCESS FULL| O_PRDCR_PROD_WIP |    11M|  7418   (3)| 00:01:30 |
-------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement

SQL> alter session set optimizer_mode = CHOOSE;

Session altered.

Elapsed: 00:00:00.00
SQL> select count(*) from ciopdba.o_prdcr_prod_wip;

            COUNT(*)
--------------------
           9,635,613

Elapsed: 00:00:04.96

Execution Plan
----------------------------------------------------------
Plan hash value: 2446809081

-----------------------------------------------
| Id  | Operation          | Name             |
-----------------------------------------------
|   0 | SELECT STATEMENT   |                  |
|   1 |  SORT AGGREGATE    |                  |
|   2 |   TABLE ACCESS FULL| O_PRDCR_PROD_WIP |
-----------------------------------------------

Note
-----
   - rule based optimizer used (consider using cbo)

CHOOSE not always ALL_ROWS

Duke Ganote, August 22, 2008 - 10:29 am UTC

I got confused by only vaguely recalling this:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3310002340673#3310080517320

whse2000:prot\ciopdba> ed
Wrote file afiedt.buf

  1  BEGIN
  2    dbms_stats.gather_table_stats
  3    ( user
  4    ,'O_PRDCR_PROD_WIP'
  5    ,estimate_percent =>  dbms_stats.auto_sample_size );
  6* END;
whse2000:prot\ciopdba> /

PL/SQL procedure successfully completed.

Elapsed: 00:00:12.15
whse2000:prot\ciopdba> alter session set optimizer_mode = choose;

Session altered.

Elapsed: 00:00:00.01
whse2000:prot\ciopdba> set autot on exp;
whse2000:prot\ciopdba> select count(*) From o_prdcr_prod_wip;

            COUNT(*)
--------------------
           9,635,613

Elapsed: 00:00:04.49

Execution Plan
----------------------------------------------------------
Plan hash value: 2446809081

-------------------------------------------------------------------------------
| Id  | Operation          | Name             | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                  |     1 |  7394   (3)| 00:01:29 |
|   1 |  SORT AGGREGATE    |                  |     1 |            |          |
|   2 |   TABLE ACCESS FULL| O_PRDCR_PROD_WIP |  9678K|  7394   (3)| 00:01:29 |
-------------------------------------------------------------------------------

Tom Kyte
August 26, 2008 - 7:18 pm UTC

choose is the same as all_rows when the CBO is used, it can be the RBO however if the objects have no statistics.


answered on the other thread.

Zahir, August 25, 2008 - 12:16 pm UTC

common mistake...

Connor, August 27, 2008 - 8:49 am UTC

It typically runs like this:

a) People are on v7, v8 or v9.

b) People take a backup of their spfile or take a backup by querying v$parameter.

c) They use that backup for some reason, and thus "optimizer_mode" is now specified explicitly to its default of CHOOSE.

d) they upgrade to to 10g and voila....

pratik, October 22, 2008 - 8:27 am UTC

Hi,

I have one query that take too much time because of use of rule based optimization. but in my database i have optimizer_mode=choose

SQL> SHOW PARAMETER OPTIMIZER_MODE

NAME                                 TYPE        VALUE
--------------------------------- ----------- -----------
optimizer_mode                       string      CHOOSE

and I execute below query to get some constraint information for "Mytable". 
SQL>SELECT A.TABLE_NAME AS CLD,C.COLUMN_NAME CCOL,D.COLUMN_NAME PCOL
 FROM USER_CONSTRAINTS A, user_constraints B, USER_CONS_COLUMNS C, USER_CONS_COLUMNS D
 WHERE A.table_name <> 'MYTABLE' and B.table_name = 'MYTABLE'
    and A.R_CONSTRAINT_NAME=B.constraint_name
    and (B.constraint_type='P' or B.constraint_type='U')
    AND C.CONSTRAINT_NAME=A.CONSTRAINT_NAME
    AND D.CONSTRAINT_NAME=A.R_CONSTRAINT_NAME
 order by A.table_name;

This query take too much time for execution. When I view plan for the execution of query, it  show me use of RULE base optimization. then i use hint with this query to force COST base optimization and it takes only few seconds to complete.
Is, the use of RULE base optimization is because of lack of statistics on dictionary tables that are used in this query? if yes, then is it require to collect statistics of dictionary table also when, we use static DD view in our query?

Thanks

Tom Kyte
October 22, 2008 - 9:03 am UTC

... Is, the use of RULE base optimization is because of lack of statistics on
dictionary tables that are used in this query? ....

given what you have typed above, yes.

"then is it require to collect..."

that would be a major change - that would be something you would want to test - I have to assume you are on a version prior to 10g (else they would have statistics and the optimizer goal would be all_rows), so you had better *test* that before just doing it.

RBO used

A reader, April 01, 2013 - 7:42 pm UTC

Oracle 11.1.0.7. Init.ora optimizer_mode = ALL_ROWS. optimizer_features_enable = 11.1.0.7. Auto stats gathering jobs are all enabled. So everything should be all CBO all the way. Some queries were mysteriously slow on Friday. Digging into AWR stats finally revealed that a SQL statement (sql_id) had spawned a plan_hash_value that was the culprit. It was doing a full table scan on a large table and consuming a lot of CPU/IO. Dumping out everything AWR knows about this SQL using
select * from table(dbms_xplan.display_awr('45knuy45ha5f2',NULL,NULL,'ADVANCED'))


Pored over the output and sure enough, the "bad" plan_hash_value was using the FTS and the Note in the output said "rule based optimizer used (consider using cbo)". I couldn't believe my eyes.

Why in the world did that one child cursor use the RBO? Any ideas?

Tom Kyte
April 22, 2013 - 1:10 pm UTC

because someone told it to.


that will be the only way.


someone altered their session and asked us to use the rule based optimizer.


A reader, April 23, 2013 - 8:21 pm UTC

Hm, I don't see how that is possible given that the query is generated from a front-end application so the query text, NLS/session environment, etc everything stays the same. I don't see how one specific child cursor of the same sql_id could suddenly decide to use the RBO.

Our DBA has logged a SR with Oracle Support but since we can't reproduce the issue at will, I don't expect much to come out of the SR.

Thanks for your time.
Tom Kyte
April 24, 2013 - 12:45 pm UTC

I've personally *never* heard of it happening - never. it is a pretty fundamental thing - the optimizer mode.

just because something was generated by a front-end application (you know, that would be *everything* there isn't anything that ISN'T generated by a front end application when you think about it) doesn't imply, infer, tell us that "everything stays the same"

you'd be surprised what coders can code.


on the other hand, it could simply be a dbms_xplan bug - especially if it was using a full scan since the RBO is notorious for using indexes.

do you have the plan and the note and all still, can you post it?

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.