Skip to Main Content
  • Questions
  • SQL Tuning Advisor- not really sure what it does

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, John.

Asked: January 27, 2016 - 1:33 pm UTC

Last updated: June 28, 2017 - 1:02 am UTC

Version: 11.2

Viewed 1000+ times

You Asked

Good Morning,

I am trying to understand what each of the three settings for the CBO really do.

1) There is the "normal", which allows the CBO to run as usual to create execution plans within a short time.
2) There is the Tuning Mode- Limited which "produces recommendations based on statistical checks, access path analysis, and SQL structure analysis. SQL profile recommendations are not generated." Will please explain how many different types of recommendations can it actually make? For instance, what is an example of a recommendation by using "statistical checks"? What is an example of a recommendation by doing an "access path analysis"? What is an example of a recommendation by using "SQL structure analysis?"
3) There is the Tuning Mode- Comprehensive which includes SQL Profile recommendations.

In which state will it recommend "SQL rewrite" or "creation of indexes"? Also, why in the world would it ask for "SQL rewrite". I thought we didn't have to worry about that since the CBO has been taking care of that for years automatically taking care of it in the "normal" mode?

I see that SQL Tuning Advisor is also doing what what the automatic maintenance job "auto optimizer stats collection" is already doing. Why?

When the SQL Tuning Advisor job runs during the automatic maintenance job, does it run as limited or comprehensive?

The Oracle group that came up with this are some funny guys. lol Those guys should just call it CBO and it has three options to set: normal, limited or comprehensive. By calling it CBO normal; CBO tuning mode which is also called ATO or tuning mode limited ; CBO tuning mode which is also called ATO or tuning mode comprehensive, is like being spun around dizzy trying to hit a pinata.

Thanks,

John


and Chris said...

Statistical checks
The statistics checks validates whether the stats on the table exist and, if so, whether they are representative of the data.

If either of these are false, then you'll get a warning under this section.

You get this in comprehensive mode.

Access path analysis
This looks to see whether there are any indexes you could create to improve the performance.

If there are any that could help, Oracle suggests them here.

You get this in limited mode.

SQL structure analysis
This highlights ways you could improve the performance by changing the SQL. This includes rewrites which could change the output of the query.

For example if you have any cartesian products (cross joins) this will highlight them. The CBO can't do this rewrite automatically because it changes the results. In most cases the cartesian product is a mistake.

Other suggestions could include replacing union with union all. The optimizer can't do this rewrite itself; you'll get different results if query blocks can return the same data.

These are reported in limited mode.

For example, here I'll create a table, put one row in it, gather stats then insert 1,000 more. So the stats are out of date:

create table t (
  x integer,
 y date
);

insert into t values (1, sysdate);
commit;
exec dbms_stats.gather_table_stats(user, 't');
insert into t 
  select rownum, sysdate+rownum/1440 from dual connect by level <= 1000;

commit;


I'll then analyze this query:

select count(*) from t t1, t t2
where  t1.x = 1
and    t2.x = 1


There's three "problems" with it:

- The stats are out of date
- There's a cartesian product
- There's no index on t(x). This returns 2 rows from 1,000. So an index on this would be good.

What does the tuning task tell us?

declare
   v_task VARCHAR2(30);
   v_sql  CLOB;

BEGIN

   /* Assign our de-dupe statement... */
   v_sql := '
select count(*) from t t1, t t2
where  t1.x = 1
and    t2.x = 1';

   /* Drop the task in case we are re-running... */
   BEGIN
      DBMS_SQLTUNE.DROP_TUNING_TASK(
         task_name => 'sql_tuning_task'
         );
   EXCEPTION
      WHEN OTHERS THEN -- ORA-13605
         NULL;
   END;

   /* Create a SQL Tuning task for our SQL... */
   v_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(
                sql_text    => v_sql,
                time_limit  => 100,
                scope       => 'COMPREHENSIVE',
                task_name   => 'sql_tuning_task',
                description => 'Demo of DBMS_SQLTUNE'
                );

   /* Execute the task... */
   DBMS_SQLTUNE.EXECUTE_TUNING_TASK(
      task_name => 'sql_tuning_task'
      );

   /* We want to run this again... */
   ROLLBACK;

END;
/

set long 80000
col recs format a90
 
select dbms_sqltune.report_tuning_task('sql_tuning_task') as recs
from   dual;


The findings on the first pass are:

1- Statistics Finding
---------------------
  Optimizer statistics for table "CHRIS"."T" and its indices are stale.

  Recommendation
  --------------
  - Consider collecting optimizer statistics for this table.
    execute dbms_stats.gather_table_stats(ownname => 'CHRIS', tabname => 'T',
            estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt =>
            'FOR ALL COLUMNS SIZE AUTO');

  Rationale
  ---------
    The optimizer requires up-to-date statistics for the table in order to
    select a good execution plan.

2- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
  An expensive cartesian product operation was found at line ID 2 of the
  execution plan.

  Recommendation
  --------------
  - Consider removing the disconnected table or view from this statement or
    add a join condition which refers to it.


After gathering stats on the table again:

exec dbms_stats.gather_table_stats(user, 't');


And re-running the analyzer, the findings are now:

1- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.

  Recommendation (estimated benefit: 66.72%)
  ------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index CHRIS.IDX$$_01760001 on CHRIS.T("X");

  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.

2- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
  An expensive cartesian product operation was found at line ID 2 of the
  execution plan.

  Recommendation
  --------------
  - Consider removing the disconnected table or view from this statement or
    add a join condition which refers to it.


Where do you see that the SQL tuning advisor is doing what the stats collection job does?

The auto tuning task runs in comprehensive mode.

The CBO is separate from the advisor. It's the advisor which has the different modes, not the CBO.

Rating

  (2 ratings)

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

Comments

Awesome explanation!

John Cantu, January 27, 2016 - 5:26 pm UTC

Awesome explanation, Chris!

Where do you see that the SQL tuning advisor is doing what the stats collection job does? I read that it "detects stale or missing stats". Based on that, I know that the automatic optimizer stats collection would do the same thing, right? the automatic optimizer stats collection would detect stale stats and then update the states. If they are missing, it will generate them.

Thanks,

John


Chris Saxon
January 27, 2016 - 5:39 pm UTC

Thanks.

The difference is the tuning advisor just tells you the stats are out of date. You still have to update them manually. Or wait for the automatic stats job which will do this.

Alex, June 26, 2017 - 9:02 pm UTC

This is probably going to come off more of a rant than a question so I apologize in advance.

I've been using the tuning advisor here and there since it was introduced. I find that it rarely "gets it right" when it comes to it's recommendations. This happened recently on a large query where it suggestion 2 differently profiles (one of which used px), an index, and sql change UNION vs UNION ALL. It advertised about an 80% improvement for each, but none made any difference.

I am aware you can't comment much without seeing the details for this example. I'm more interested in understanding in general, why this happens. Mind you, I am letting it run for hours so I'm pretty surprised that it can be so far off after all that.

Thanks.
Connor McDonald
June 28, 2017 - 1:02 am UTC

No apology required.

Like any feature in the database, I know plenty of people that love the utility...and plenty that dont :-)

The underlying implementation of the SQL Tuning advisor is described here by the people that wrote it

http://www.oracle.com/technetwork/database/manageability/vldb-sqltune-129632.pdf

It doesn't claim to be a miracle worker.

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here