SlideShare a Scribd company logo
1 of 119
Download to read offline
Managing Statistics for
Optimal Query Performance




Karen Morton
karen.morton@agilex.com
OOW 2009
2009 October 13
1:00pm-2:00pm
Moscone South Room 305
Your speaker…

•Karen Morton
  – Sr. Principal Database Engineer
  – Educator, DBA, developer,
    consultant, researcher, author,
    speaker, …




•Come see me…
  – karenmorton.blogspot.com
  – An Oracle user group near you
Math
 or

      Magic   ?
“I accept no responsibility for
statistics, which are a form of magic
beyond my comprehension.”
                     — Robertson Davies
SQL>desc deck
 Name            Null?    Type
 -------------   -------- -------------
 SUIT            NOT NULL VARCHAR2(10)
 CARD                     VARCHAR2(10)
 COLOR                    VARCHAR2(5)
 FACEVAL         NOT NULL NUMBER(2)
Table:   DECK

Statistic         Current value
---------------   -------------------
# rows            52
Blocks            5
Avg Row Len       20
Degree            1
Sample Size       52


Column Name NDV Nulls # Nulls   Density Length Low Value High Value
----------- --- ----- -------   ------- ------ ---------- -----------
SUIT          4 N           0   .250000      8 Clubs      Spades
CARD         13 Y           0   .076923      5 Ace        Two
COLOR         2 Y           0   .500000      5 Black      Red
FACEVAL      13 N           0   .076923      3 1          13


Index Name      Col# Column Name    Unique? Height Leaf Blks Distinct Keys
-------------- ----- ------------   ------- ------ ---------- -------------
DECK_PK            1 SUIT           Y            1          1            52
                   2 FACEVAL
DECK_CARD_IDX      1 CARD           N            1         1            13
DECK_COLOR_IDX     1 COLOR          N            1         1             2
Cardinality

The estimated number of rows
a query is expected to return.



   number of rows in table
              x
    predicate selectivity
select *
  from deck
 order by suit, faceval ;




        Cardinality
        52 x 1 = 52
SQL>select * from deck order by suit, faceval ;

52 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3142028678

----------------------------------------------------------------------
| Id | Operation                    | Name    | Rows | Bytes | Cost |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |    52 | 1040 |      2|
|   1 | TABLE ACCESS BY INDEX ROWID| DECK     |    52 | 1040 |      2|
|   2 |   INDEX FULL SCAN           | DECK_PK |    52 |       |     1|
----------------------------------------------------------------------




                                                                   *
select *
  from deck
 where color = 'Black' ;




        Cardinality
       52 x 1/2 = 26
SQL>select * from deck where color = 'Black' ;

26 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1366616955

----------------------------------------------------------------------------
| Id | Operation                    | Name          | Rows | Bytes | Cost |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |    26 |   520 |     2|
|   1 | TABLE ACCESS BY INDEX ROWID| DECK           |    26 |   520 |     2|
|* 2 |    INDEX RANGE SCAN          | DECK_COLOR_ID |    26 |       |     1|
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - access("COLOR"='Black')
select   *
  from   deck
 where   card = 'Ace'
   and   suit = 'Spades' ;



        Cardinality
   52 x 1/13 x 1/4 = 1
SQL>select *
  2    from deck
  3   where card = 'Ace'
  4     and suit = 'Spades' ;

1 row selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2030372774

----------------------------------------------------------------------------
| Id | Operation                    | Name          | Rows | Bytes | Cost |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |     1 |    20 |     2|
|* 1 | TABLE ACCESS BY INDEX ROWID| DECK            |     1 |    20 |     2|
|* 2 |    INDEX RANGE SCAN          | DECK_CARD_IDX |     4 |       |     1|
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  1 - filter("SUIT"='Spades')
  2 - access("CARD"='Ace')
select *
  from deck
 where faceval > 10 ;




         Cardinality
          (13 – 10) High Value - Predicate Value
    52 x
          (13 – 1) High Value - Low Value
            = 13
SQL>select *
  2    from deck
  3   where faceval > 10 ;

12 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1303963799

---------------------------------------------------------
| Id | Operation          | Name | Rows | Bytes | Cost |
---------------------------------------------------------
|   0 | SELECT STATEMENT |       |    13 |   260 |     3|
|* 1 | TABLE ACCESS FULL| DECK |      13 |   260 |     3|
---------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  1 - filter("FACEVAL">10)
select *
  from deck
 where card = 'Ace' ;




        Cardinality
       52 x 1/13 = 4
SQL>select * from deck where card = :b1 ;

4 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 2030372774

----------------------------------------------------------------------------
| Id | Operation                    | Name          | Rows | Bytes | Cost |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |     4 |    80 |     2|
|   1 | TABLE ACCESS BY INDEX ROWID| DECK           |     4 |    80 |     2|
|* 2 |    INDEX RANGE SCAN          | DECK_CARD_IDX |     4 |       |     1|
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - access("CARD"=:B1)
Math
 or

      Magic    ?

                 Maybe it's a
              little bit of both!
What's the best method
for collecting statistics?
It depends.
Statistics that don't reasonably
       describe your data
…lead to poor
cardinality estimates
…which leads to poor
access path selection
…which leads to poor
join method selection
…which leads to poor
 join order selection
…which leads to poor
SQL execution times.
Statistics matter!
Automatic
    vs


 Manual
Automatic
 Collections
Objects must change
   by at least 10%
Collection scheduled
   during nightly
maintenance window
dbms_stats
gather_database_stats_job_proc
Prioritizes collection
   in order by objects
which most need updating
Most functional when
data changes at a slow
  to moderate rate
Volatile tables and
   large bulk loads
are good candidates
for manual collection
Automatic
 doesn't mean
   accurate
(for your data)
Automatic
Collection
 Defaults
SQL>exec dbms_stats.gather_table_stats (ownname=>?, tabname=>?) ;

partname           NULL
cascade            DBMS_STATS.AUTO_CASCADE
estimate_percent   DBMS_STATS.AUTO_SAMPLE_SIZE
stattab            NULL
block_sample       FALSE
statid             NULL
method_opt         FOR ALL COLUMNS SIZE AUTO
statown            NULL
degree             1 or value based on number of CPUs
                    and initialization parameters
force              FALSE
granularity        AUTO (value is based on partitioning type)
no_invalidate      DBMS_STATS.AUTO_INVALIDATE
cascade=>
    AUTO_CASCADE

Allow Oracle to determine
    whether or not to
  gather index statistics
estimate_percent=>
 AUTO_SAMPLE_SIZE

Allow Oracle to determine
       sample size
method_opt=>
     FOR ALL COLUMNS
        SIZE AUTO

Allow Oracle to determine when
 to gather histogram statistics

                          SYS.COL_USAGE$
no_invalidate=>
     AUTO_INVALIDATE

Allow Oracle to determine when
to invalidate dependent cursors
Goal

 Collect statistics that are
  "good enough" to meet
most needs most of the time.
Say you were standing with one
foot in the oven and one foot in
an ice bucket. According to the
 percentage people, you would
   be perfectly comfortable.
                   – Bobby Bragan
Manual
Collections
dbms_stats
     gather_*_stats

* = database, schema, table, index, etc.
Is it common for your users to get
slammed with performance problems
shortly after statistics are updated?
Does performance decline before a
10% data change occurs?
Do low and high values for a column
change significantly between
automatic collections?
Does your application performance
seem "sensitive" to changing user
counts as well as data volume changes?
If you answered "Yes"
   to one or more of
   these questions...
your application's
 unique needs may
be best served with
 manual collection.
Test. Test. Test.
Dynamic
Sampling
optimizer_dynamic_sampling
         parameter

    dynamic_sampling
          hint
SQL>create table depend_test as
  2 select mod(num, 100) c1,
  3         mod(num, 100) c2,
  4         mod(num, 75) c3,
  5         mod(num, 30) c4
  6    from (select level num from dual
  7                     connect by level <= 10001);

Table created.

SQL>exec dbms_stats.gather_table_stats( user, 'depend_test',
estimate_percent => null, method_opt => 'for all columns size
1');

PL/SQL procedure successfully completed.
Statistic          Current value
---------------    --------------
# rows             10001
Blocks             28
Avg Row Len        11
Sample Size        10001
Monitoring         YES

Column    NDV   Density AvgLen Histogram LowVal   HighVal
-------   ---   ------- ------ --------- ------   -------
C1        100   .010000      3 NONE (1) 0         99
C2        100   .010000      3 NONE (1) 0         99
C3         75   .013333      3 NONE (1) 0         74
C4         30   .033333      3 NONE (1) 0         29
SQL>set autotrace traceonly explain
SQL>select count(*) from depend_test where c1 = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 3984367388
----------------------------------------------------------------------------------
| Id | Operation           | Name        | Rows | Bytes | Cost (%CPU)| Time      |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |     3 |     8   (0)| 00:00:01 |
|   1 | SORT AGGREGATE     |             |     1 |     3 |            |          |
|* 2 |    TABLE ACCESS FULL| DEPEND_TEST |   100 |   300 |     8   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("C1"=10)
SQL>set autotrace traceonly explain
SQL>select count(*) from depend_test where c1 = 10 and c2 = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 3984367388

----------------------------------------------------------------------------------
| Id | Operation           | Name        | Rows | Bytes | Cost (%CPU)| Time      |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |     6 |     8   (0)| 00:00:01 |
|   1 | SORT AGGREGATE     |             |     1 |     6 |            |          |
|* 2 |    TABLE ACCESS FULL| DEPEND_TEST |     1 |     6 |     8   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("C1"=10 AND "C2"=10)
SQL>set autotrace traceonly explain
SQL>select /*+ dynamic_sampling (4) */ count(*)
  2 from depend_test where c1 = 10 and c2 = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 3984367388

----------------------------------------------------------------------------------
| Id | Operation           | Name        | Rows | Bytes | Cost (%CPU)| Time      |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |     6 |     8   (0)| 00:00:01 |
|   1 | SORT AGGREGATE     |             |     1 |     6 |            |          |
|* 2 |    TABLE ACCESS FULL| DEPEND_TEST |   100 |   600 |     8   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("C1"=10 AND "C2"=10)

Note
-----
   - dynamic sampling used for this statement
11g Extended Statistics
SQL>   select dbms_stats.create_extended_stats(ownname=>user,
  2    tabname => 'DEPEND_TEST',
  3    extension => '(c1, c2)' ) AS c1_c2_correlation
  4    from dual ;

C1_C2_CORRELATION
-------------------------------------------------------------
SYS_STUF3GLKIOP5F4B0BTTCFTMX0W

SQL> exec dbms_stats.gather_table_stats( user, 'depend_test');

PL/SQL procedure successfully completed.
SQL> set autotrace traceonly explain
SQL> select count(*) from depend_test where c1 = 10 and c2 = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 3984367388
----------------------------------------------------------------------------------
| Id | Operation           | Name        | Rows | Bytes | Cost (%CPU)| Time      |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |     6 |     9   (0)| 00:00:01 |
|   1 | SORT AGGREGATE     |             |     1 |     6 |            |          |
|* 2 |    TABLE ACCESS FULL| DEPEND_TEST |   100 |   600 |     9   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("C1"=10 AND "C2"=10)
Setting
Statistics
dbms_stats
set_column_stats
 set_index_stats
 set_table_stats
It's OK.

Really.
Why guess
(i.e. gather stats)
when you know!
Common
Performance
 Problems
3 areas where
   non-representative
statistics cause problems
1
    Data Skew
The optimizer assumes
 uniform distribution
  of column values.
Color column - uniform distribution
Color column – skewed distribution
Data skew must be
  identified with
   a histogram.
Table:    obj_tab
                                                 100% Statistics
Statistic           Current value           FOR ALL COLUMNS SIZE 1
---------------     --------------
# rows              1601874
Blocks              22321
Avg Row Len         94
Sample Size         1601874
Monitoring          YES


Column:   object_type     (has 36 distinct values)

OBJECT_TYPE                          PCT_TOTAL
-------------------------------      ---------
WINDOW GROUP - PROGRAM                 .00-.02
EVALUATION CONTEXT - XML SCHEMA        .03-.05
OPERATOR - PROCEDURE                   .11-.17
LIBRARY - TYPE BODY                    .30-.35
FUNCTION - INDEX PARTITION             .54-.64
JAVA RESOURCE - PACKAGE              1.54-1.69
TABLE - VIEW                         3.44-7.35
JAVA CLASS                               32.80
SYNONYM                                  40.01
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 16yy3p8sstr28, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id,
status from obj_tab where object_type = 'PROCEDURE'

Plan hash value: 2862749165
--------------------------------------------------------------------------------
| Id | Operation                    | Name         | E-Rows | A-Rows | Buffers |
--------------------------------------------------------------------------------
|   1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB       | 44497 |    2720 |    1237 |
|* 2 |    INDEX RANGE SCAN          | OBJ_TYPE_IDX | 44497 |    2720 |     193 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"='PROCEDURE')



                                                         E-Rows = 1/36 x 1,601,874




                                                          R = .06 seconds
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 9u6ppkh5mhr8v, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id,
status from obj_tab where object_type = 'SYNONYM'

Plan hash value: 2862749165

--------------------------------------------------------------------------------
| Id | Operation                    | Name         | E-Rows | A-Rows | Buffers |
--------------------------------------------------------------------------------
|   1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB       | 44497 |     640K|     104K|
|* 2 |    INDEX RANGE SCAN          | OBJ_TYPE_IDX | 44497 |     640K|   44082 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - access("OBJECT_TYPE"='SYNONYM')


                                                         E-Rows = 1/36 x 1,601,874



                                                        R = 14.25 seconds
Re-collect statistics

          100%
FOR ALL COLUMNS SIZE AUTO
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 16yy3p8sstr28, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id,
status from obj_tab where object_type = 'PROCEDURE'

Plan hash value: 2862749165
--------------------------------------------------------------------------------
| Id | Operation                    | Name         | E-Rows | A-Rows | Buffers |
--------------------------------------------------------------------------------
|   1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB       |   2720 |   2720 |    1237 |
|* 2 |    INDEX RANGE SCAN          | OBJ_TYPE_IDX |   2720 |   2720 |     193 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"='PROCEDURE')



                                                      E-Rows = histogram x 1,601,874



                                                              R = .07 seconds
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 9u6ppkh5mhr8v, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id,
status from obj_tab where object_type = 'SYNONYM'

Plan hash value: 2748991475

-----------------------------------------------------------------
| Id | Operation          | Name    | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------
|* 1 | TABLE ACCESS FULL| OBJ_TAB |      640K|    640K|   64263 |
-----------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("OBJECT_TYPE"='SYNONYM')



                                     E-Rows = histogram x 1,601,874




                                                           R = 3.36 seconds
                                                                  vs 14.25 seconds
Histograms are
important for more
  reasons than just
 helping determine
the access method.
2
    Bind Peeking
During hard parse, the optimizer
 "peeks" at the bind value and
    uses it to determine the
        execution plan.
But, what if your
data is skewed?




                    11g
SQL> variable objtype varchar2(19)
SQL> exec :objtype := 'PROCEDURE';

PL/SQL procedure successfully completed.

SQL> select /*+ gather_plan_statistics */ count(*) ct
  2 from big_tab
  3 where object_type = :objtype ;

             CT
---------------
           4416

1 row selected.

SQL>
SQL> select * from table
(dbms_xplan.display_cursor('211078a9adzak',0,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
---------------------------------------
SQL_ID 211078a9adzak, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) ct from big_tab where
object_type = :objtype

Plan hash value: 154074842
-------------------------------------------------------------------------
| Id | Operation           | Name           | E-Rows | A-Rows | Buffers |
-------------------------------------------------------------------------
|   1 | SORT AGGREGATE     |                |      1 |      1 |      16 |
|* 2 |    INDEX RANGE SCAN| BIG_OBJTYPE_IDX |   4416 |   4416 |      16 |
-------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"=:OBJTYPE)
SQL> select child_number, executions, buffer_gets,
  2         is_bind_sensitive, is_bind_aware, is_shareable
  3 from v$sql where sql_id = '211078a9adzak' ;

     CHILD_NUMBER   =   0
       EXECUTIONS   =   1
      BUFFER_GETS   =   16
IS_BIND_SENSITIVE   =   N
    IS_BIND_AWARE   =   N
     IS_SHAREABLE   =   Y
SQL> variable objtype varchar2(19)
SQL> exec :objtype := 'SYNONYM';

PL/SQL procedure successfully completed.

SQL> select /*+ gather_plan_statistics */ count(*) ct
  2 from big_tab
  3 where object_type = :objtype ;

              CT
----------------
          854176

1 row selected.

SQL>
SQL> select * from table
(dbms_xplan.display_cursor('211078a9adzak',0,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
---------------------------------------
SQL_ID 211078a9adzak, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) ct from big_tab where
object_type = :objtype

Plan hash value: 154074842
-------------------------------------------------------------------------
| Id | Operation           | Name           | E-Rows | A-Rows | Buffers |
-------------------------------------------------------------------------
|   1 | SORT AGGREGATE     |                |      1 |      1 |    2263 |
|* 2 |    INDEX RANGE SCAN| BIG_OBJTYPE_IDX |   4416 |   854K |    2263 |
-------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"=:OBJTYPE)
SQL> select child_number, executions, buffer_gets,
  2         is_bind_sensitive, is_bind_aware, is_shareable
  3 from v$sql where sql_id = '211078a9adzak' ;

     CHILD_NUMBER   =   0
       EXECUTIONS   =   2
      BUFFER_GETS   =   2279   (2263 + 16)
IS_BIND_SENSITIVE   =   Y
    IS_BIND_AWARE   =   N
     IS_SHAREABLE   =   Y
SQL> variable objtype varchar2(19)
SQL> exec :objtype := 'SYNONYM';

PL/SQL procedure successfully completed.


PLAN_TABLE_OUTPUT
---------------------------------------
SQL_ID 211078a9adzak, child number 1
-------------------------------------
select /*+ gather_plan_statistics */ count(*) ct from big_tab where
object_type = :objtype

Plan hash value: 1315022418
-----------------------------------------------------------------------------
| Id | Operation              | Name            | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------------
|   1 | SORT AGGREGATE        |                 |      1 |      1 |    6016 |
|* 2 |    INDEX FAST FULL SCAN| BIG_OBJTYPE_IDX |   854K |   854K |    6016 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"=:OBJTYPE)
SQL> select child_number, executions, buffer_gets,
  2         is_bind_sensitive, is_bind_aware, is_shareable
  3 from v$sql where sql_id = '211078a9adzak' ;


     CHILD_NUMBER   =   0           CHILD_NUMBER   =   1
       EXECUTIONS   =   2             EXECUTIONS   =   1
      BUFFER_GETS   =   2279         BUFFER_GETS   =   6016
IS_BIND_SENSITIVE   =   Y      IS_BIND_SENSITIVE   =   Y
    IS_BIND_AWARE   =   N          IS_BIND_AWARE   =   Y
     IS_SHAREABLE   =   N           IS_SHAREABLE   =   Y
SQL> variable objtype varchar2(19)
SQL> exec :objtype := 'PROCEDURE';

PL/SQL procedure successfully completed.


PLAN_TABLE_OUTPUT
---------------------------------------
SQL_ID 211078a9adzak, child number 2
-------------------------------------
select /*+ gather_plan_statistics */ count(*) ct from big_tab where
object_type = :objtype

Plan hash value: 154074842
-------------------------------------------------------------------------
| Id | Operation           | Name           | E-Rows | A-Rows | Buffers |
-------------------------------------------------------------------------
|   1 | SORT AGGREGATE     |                |      1 |      1 |      16 |
|* 2 |    INDEX RANGE SCAN| BIG_OBJTYPE_IDX |   4416 |   4416 |      16 |
-------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE"=:OBJTYPE)
SQL> select child_number, executions, buffer_gets,
  2         is_bind_sensitive, is_bind_aware, is_shareable
  3 from v$sql where sql_id = '211078a9adzak' ;


     CHILD_NUMBER   =   0           CHILD_NUMBER   =   1
       EXECUTIONS   =   2             EXECUTIONS   =   1
      BUFFER_GETS   =   2279         BUFFER_GETS   =   6016
IS_BIND_SENSITIVE   =   Y      IS_BIND_SENSITIVE   =   Y
    IS_BIND_AWARE   =   N          IS_BIND_AWARE   =   Y
     IS_SHAREABLE   =   N           IS_SHAREABLE   =   Y



                    CHILD_NUMBER   =   2
                      EXECUTIONS   =   1
                     BUFFER_GETS   =   16
               IS_BIND_SENSITIVE   =   Y
                   IS_BIND_AWARE   =   Y
                    IS_SHAREABLE   =   Y
10g will create only 1 plan.


11g will create plans as needed
     to cover data skew.
Handling bind peeking
is more of a coding issue
  than a statistics issue.
3
      Incorrect
    High and Low
        Values
To derive the cardinality
estimate for range predicates,
  the optimizer uses the low
   and high value statistics.
Table:   hi_lo_t

Statistic          Current value
---------------    ---------------------
# rows             100000
Blocks             180
Avg Row Len        7
Sample Size        100000
Monitoring         YES

Column     NDV Nulls   Density AvgLen Histogram LowVal   HighVal
------- ------ -----   ------- ------ --------- ------   -------
A       100000 N       .000010      5 NONE (1) 10        100009
B           10 Y       .100000      3 NONE (1) 9         18




                                               100% Statistics
                                           FOR ALL COLUMNS SIZE 1
select count(a)
     from hi_lo_t
    where b < 11 ;



        (   11 – 9
            18 – 9   )   Predicate value – Low value

                         High value – Low value




100000 rows x .22222 = 22222
select count(a) from hi_lo_t where b < 11

Plan hash value: 3307858660

------------------------------------------------------------------
| Id | Operation           | Name    | E-Rows | A-Rows | Buffers |
------------------------------------------------------------------
|   1 | SORT AGGREGATE     |         |      1 |      1 |     184 |
|* 2 |    TABLE ACCESS FULL| HI_LO_T | 22222 | 20000 |       184 |
------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - filter("B"<11)
select count(a)
      from hi_lo_t
     where b < 4 ;



.10 x   (   1 +
                 4 – 9
                18 – 9   )   Predicate value – Low value

                             High value – Low value




 100000 rows x .04444 = 4444
select count(a) from hi_lo_t where b < 4

Plan hash value: 3307858660

------------------------------------------------------------------
| Id | Operation           | Name    | E-Rows | A-Rows | Buffers |
------------------------------------------------------------------
|   1 | SORT AGGREGATE     |         |      1 |      1 |     184 |
|* 2 |    TABLE ACCESS FULL| HI_LO_T |   4444 |      0 |     184 |
------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - filter("B"<4)
METHOD_OPT=>
'FOR ALL INDEXED COLUMNS'




            Be cautious of using this!
If column is not indexed,
no statistics are collected.
select count(a) from hi_lo_t where b = 12

Plan hash value: 3307858660

------------------------------------------------------------------
| Id | Operation           | Name    | E-Rows | A-Rows | Buffers |
------------------------------------------------------------------
|   1 | SORT AGGREGATE     |         |      1 |      1 |     184 |
|* 2 |    TABLE ACCESS FULL| HI_LO_T |   1000 | 10000 |      184 |
------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  2 - filter("B"=12)




     Without statistics, a 10% default is used.
Result:
Cardinality estimates that are
 orders of magnitude "off"
Conclusion
Why guess when you can know.
Thoroughly test and
  document your
statistics collection
      strategy.
Check default options
  particularly when
     upgrading.

   Things change.
Regularly check
statistics and compare
to previous collections
  for any anomalies.

                 10.2.0.4 and above
                 dbms_stats.diff_table_stats_*
Don't ignore
 your data.
There is no
 single strategy
that works best
  for everyone.
Statistics must reasonably
represent your actual data.
Understanding basic
 optimizer statistics
computations is key.
The more you know,
 the more likely you
   are to succeed.
Thank You!
Q U E S T I O N S
 A N S W E R S

More Related Content

What's hot

Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by exampleMauro Pagano
 
Histograms in 12c era
Histograms in 12c eraHistograms in 12c era
Histograms in 12c eraMauro Pagano
 
SQL Plan Directives explained
SQL Plan Directives explainedSQL Plan Directives explained
SQL Plan Directives explainedMauro Pagano
 
Is your SQL Exadata-aware?
Is your SQL Exadata-aware?Is your SQL Exadata-aware?
Is your SQL Exadata-aware?Mauro Pagano
 
Full Table Scan: friend or foe
Full Table Scan: friend or foeFull Table Scan: friend or foe
Full Table Scan: friend or foeMauro Pagano
 
Oracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatFranck Pachot
 
Adaptive Query Optimization
Adaptive Query OptimizationAdaptive Query Optimization
Adaptive Query OptimizationAnju Garg
 
SQLチューニング総合診療Oracle CloudWorld出張所
SQLチューニング総合診療Oracle CloudWorld出張所SQLチューニング総合診療Oracle CloudWorld出張所
SQLチューニング総合診療Oracle CloudWorld出張所Hiroshi Sekiguchi
 
Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010Riyaj Shamsudeen
 
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルX
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルXdb tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルX
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルXHiroshi Sekiguchi
 
MariaDB: Engine Independent Table Statistics, including histograms
MariaDB: Engine Independent Table Statistics, including histogramsMariaDB: Engine Independent Table Statistics, including histograms
MariaDB: Engine Independent Table Statistics, including histogramsSergey Petrunya
 
Understanding Optimizer-Statistics-for-Developers
Understanding Optimizer-Statistics-for-DevelopersUnderstanding Optimizer-Statistics-for-Developers
Understanding Optimizer-Statistics-for-DevelopersEnkitec
 
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...Sergey Petrunya
 
Indexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index StatementIndexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index StatementSean Scott
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Hemant K Chitale
 
Oracle Diagnostics : Joins - 1
Oracle Diagnostics : Joins - 1Oracle Diagnostics : Joins - 1
Oracle Diagnostics : Joins - 1Hemant K Chitale
 
Demystifying cost based optimization
Demystifying cost based optimizationDemystifying cost based optimization
Demystifying cost based optimizationRiyaj Shamsudeen
 
Character Encoding - MySQL DevRoom - FOSDEM 2015
Character Encoding - MySQL DevRoom - FOSDEM 2015Character Encoding - MySQL DevRoom - FOSDEM 2015
Character Encoding - MySQL DevRoom - FOSDEM 2015mushupl
 
More than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cMore than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cGuatemala User Group
 

What's hot (20)

Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by example
 
Histograms in 12c era
Histograms in 12c eraHistograms in 12c era
Histograms in 12c era
 
SQL Plan Directives explained
SQL Plan Directives explainedSQL Plan Directives explained
SQL Plan Directives explained
 
Is your SQL Exadata-aware?
Is your SQL Exadata-aware?Is your SQL Exadata-aware?
Is your SQL Exadata-aware?
 
Full Table Scan: friend or foe
Full Table Scan: friend or foeFull Table Scan: friend or foe
Full Table Scan: friend or foe
 
Oracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor format
 
PoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expériencePoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expérience
 
Adaptive Query Optimization
Adaptive Query OptimizationAdaptive Query Optimization
Adaptive Query Optimization
 
SQLチューニング総合診療Oracle CloudWorld出張所
SQLチューニング総合診療Oracle CloudWorld出張所SQLチューニング総合診療Oracle CloudWorld出張所
SQLチューニング総合診療Oracle CloudWorld出張所
 
Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010
 
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルX
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルXdb tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルX
db tech showcase Tokyo 2014 - L36 - JPOUG : SQLチューニング総合診療所 ケースファイルX
 
MariaDB: Engine Independent Table Statistics, including histograms
MariaDB: Engine Independent Table Statistics, including histogramsMariaDB: Engine Independent Table Statistics, including histograms
MariaDB: Engine Independent Table Statistics, including histograms
 
Understanding Optimizer-Statistics-for-Developers
Understanding Optimizer-Statistics-for-DevelopersUnderstanding Optimizer-Statistics-for-Developers
Understanding Optimizer-Statistics-for-Developers
 
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
 
Indexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index StatementIndexing Strategies for Oracle Databases - Beyond the Create Index Statement
Indexing Strategies for Oracle Databases - Beyond the Create Index Statement
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)
 
Oracle Diagnostics : Joins - 1
Oracle Diagnostics : Joins - 1Oracle Diagnostics : Joins - 1
Oracle Diagnostics : Joins - 1
 
Demystifying cost based optimization
Demystifying cost based optimizationDemystifying cost based optimization
Demystifying cost based optimization
 
Character Encoding - MySQL DevRoom - FOSDEM 2015
Character Encoding - MySQL DevRoom - FOSDEM 2015Character Encoding - MySQL DevRoom - FOSDEM 2015
Character Encoding - MySQL DevRoom - FOSDEM 2015
 
More than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cMore than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12c
 

Viewers also liked

Incremental statistics for partitioned tables in 11g by wwf from ebay COC
Incremental statistics for partitioned tables in 11g  by wwf from ebay COCIncremental statistics for partitioned tables in 11g  by wwf from ebay COC
Incremental statistics for partitioned tables in 11g by wwf from ebay COCLouis liu
 
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]Kyle Hailey
 
コミュニケーションソフトウェアを創るということ
コミュニケーションソフトウェアを創るということコミュニケーションソフトウェアを創るということ
コミュニケーションソフトウェアを創るということKazuho Oku
 
Bibliografia soundscpe, sound, landscape
Bibliografia soundscpe, sound, landscapeBibliografia soundscpe, sound, landscape
Bibliografia soundscpe, sound, landscapeagata stanisz
 
Fscons Keynote Free Software Feminism
Fscons Keynote Free Software FeminismFscons Keynote Free Software Feminism
Fscons Keynote Free Software Feminismludost
 
The Art of Reconstrcution workshop
The Art of Reconstrcution workshopThe Art of Reconstrcution workshop
The Art of Reconstrcution workshopJoss Winn
 
Weblin説明資料20080826
Weblin説明資料20080826Weblin説明資料20080826
Weblin説明資料20080826meltingdots
 
Building advocacy and trust: social media for engagement
Building advocacy and trust: social media for engagementBuilding advocacy and trust: social media for engagement
Building advocacy and trust: social media for engagementLis Parcell
 
Garter Snake by A.J.Delorme
Garter Snake by A.J.DelormeGarter Snake by A.J.Delorme
Garter Snake by A.J.Delormevebrya
 
A Long Walk to Water: Lesson9 unit2
A Long Walk to Water: Lesson9 unit2A Long Walk to Water: Lesson9 unit2
A Long Walk to Water: Lesson9 unit2Terri Weiss
 
What's in a habitat?
What's in a habitat?What's in a habitat?
What's in a habitat?Russell Ogden
 
Рынок смартфонов и планшетов США. 2012 и 2013
Рынок смартфонов и планшетов США. 2012 и 2013Рынок смартфонов и планшетов США. 2012 и 2013
Рынок смартфонов и планшетов США. 2012 и 2013Maria Podolyak
 
My Learning Goal
My Learning GoalMy Learning Goal
My Learning Goalgueste41a29
 
Tips for grabbing and holding attention in online courses
Tips for grabbing and holding attention in online coursesTips for grabbing and holding attention in online courses
Tips for grabbing and holding attention in online coursesDr Graeme Salter
 
A Long Walk to Water - Lssn 7
A Long Walk to Water - Lssn 7A Long Walk to Water - Lssn 7
A Long Walk to Water - Lssn 7Terri Weiss
 
A SALUTE TO MOTHERS 2008
A SALUTE TO MOTHERS 2008A SALUTE TO MOTHERS 2008
A SALUTE TO MOTHERS 2008ROWENA REYES
 

Viewers also liked (20)

AWR and ASH in an EM12c World
AWR and ASH in an EM12c WorldAWR and ASH in an EM12c World
AWR and ASH in an EM12c World
 
Incremental statistics for partitioned tables in 11g by wwf from ebay COC
Incremental statistics for partitioned tables in 11g  by wwf from ebay COCIncremental statistics for partitioned tables in 11g  by wwf from ebay COC
Incremental statistics for partitioned tables in 11g by wwf from ebay COC
 
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
 
コミュニケーションソフトウェアを創るということ
コミュニケーションソフトウェアを創るということコミュニケーションソフトウェアを創るということ
コミュニケーションソフトウェアを創るということ
 
Bibliografia soundscpe, sound, landscape
Bibliografia soundscpe, sound, landscapeBibliografia soundscpe, sound, landscape
Bibliografia soundscpe, sound, landscape
 
Fscons Keynote Free Software Feminism
Fscons Keynote Free Software FeminismFscons Keynote Free Software Feminism
Fscons Keynote Free Software Feminism
 
The Art of Reconstrcution workshop
The Art of Reconstrcution workshopThe Art of Reconstrcution workshop
The Art of Reconstrcution workshop
 
The Roots of Innovation
The Roots of InnovationThe Roots of Innovation
The Roots of Innovation
 
JSX
JSXJSX
JSX
 
Weblin説明資料20080826
Weblin説明資料20080826Weblin説明資料20080826
Weblin説明資料20080826
 
Building advocacy and trust: social media for engagement
Building advocacy and trust: social media for engagementBuilding advocacy and trust: social media for engagement
Building advocacy and trust: social media for engagement
 
Garter Snake by A.J.Delorme
Garter Snake by A.J.DelormeGarter Snake by A.J.Delorme
Garter Snake by A.J.Delorme
 
A Long Walk to Water: Lesson9 unit2
A Long Walk to Water: Lesson9 unit2A Long Walk to Water: Lesson9 unit2
A Long Walk to Water: Lesson9 unit2
 
What's in a habitat?
What's in a habitat?What's in a habitat?
What's in a habitat?
 
Рынок смартфонов и планшетов США. 2012 и 2013
Рынок смартфонов и планшетов США. 2012 и 2013Рынок смартфонов и планшетов США. 2012 и 2013
Рынок смартфонов и планшетов США. 2012 и 2013
 
My Learning Goal
My Learning GoalMy Learning Goal
My Learning Goal
 
Kibice
KibiceKibice
Kibice
 
Tips for grabbing and holding attention in online courses
Tips for grabbing and holding attention in online coursesTips for grabbing and holding attention in online courses
Tips for grabbing and holding attention in online courses
 
A Long Walk to Water - Lssn 7
A Long Walk to Water - Lssn 7A Long Walk to Water - Lssn 7
A Long Walk to Water - Lssn 7
 
A SALUTE TO MOTHERS 2008
A SALUTE TO MOTHERS 2008A SALUTE TO MOTHERS 2008
A SALUTE TO MOTHERS 2008
 

Similar to Managing Statistics for Optimal Query Performance

Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleGuatemala User Group
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sqlj9soto
 
A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013Connor McDonald
 
Dbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersDbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersRiyaj Shamsudeen
 
Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Keshav Murthy
 
Sydney Oracle Meetup - access paths
Sydney Oracle Meetup - access pathsSydney Oracle Meetup - access paths
Sydney Oracle Meetup - access pathspaulguerin
 
All on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor SharingAll on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor SharingMohamed Houri
 
New Tuning Features in Oracle 11g - How to make your database as boring as po...
New Tuning Features in Oracle 11g - How to make your database as boring as po...New Tuning Features in Oracle 11g - How to make your database as boring as po...
New Tuning Features in Oracle 11g - How to make your database as boring as po...Sage Computing Services
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan DirectivesFranck Pachot
 
EvolveExecutionPlans.pdf
EvolveExecutionPlans.pdfEvolveExecutionPlans.pdf
EvolveExecutionPlans.pdfPraveenPolu1
 
MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015Dave Stokes
 
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015Dave Stokes
 
Oracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_shareOracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_shareThomas Teske
 
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...Informatik Aktuell
 

Similar to Managing Statistics for Optimal Query Performance (20)

Oracle 12c SPM
Oracle 12c SPMOracle 12c SPM
Oracle 12c SPM
 
Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1Oracle 11g caracteristicas poco documentadas 3 en 1
Oracle 11g caracteristicas poco documentadas 3 en 1
 
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
 
Writing efficient sql
Writing efficient sqlWriting efficient sql
Writing efficient sql
 
sqltuningcardinality1(1).ppt
sqltuningcardinality1(1).pptsqltuningcardinality1(1).ppt
sqltuningcardinality1(1).ppt
 
A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013
 
Dbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersDbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineers
 
Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1Informix Warehouse Accelerator (IWA) features in version 12.1
Informix Warehouse Accelerator (IWA) features in version 12.1
 
Sydney Oracle Meetup - access paths
Sydney Oracle Meetup - access pathsSydney Oracle Meetup - access paths
Sydney Oracle Meetup - access paths
 
All on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor SharingAll on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor Sharing
 
New Tuning Features in Oracle 11g - How to make your database as boring as po...
New Tuning Features in Oracle 11g - How to make your database as boring as po...New Tuning Features in Oracle 11g - How to make your database as boring as po...
New Tuning Features in Oracle 11g - How to make your database as boring as po...
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan Directives
 
EvolveExecutionPlans.pdf
EvolveExecutionPlans.pdfEvolveExecutionPlans.pdf
EvolveExecutionPlans.pdf
 
SQLQueries
SQLQueriesSQLQueries
SQLQueries
 
MySQL SQL Tutorial
MySQL SQL TutorialMySQL SQL Tutorial
MySQL SQL Tutorial
 
MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015
 
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
 
Oracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_shareOracle 122 partitioning_in_action_slide_share
Oracle 122 partitioning_in_action_slide_share
 
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
Randolf Geist – IT-Tage 2015 – Oracle Parallel Execution – Analyse und Troubl...
 
5 Cool Things About SQL
5 Cool Things About SQL5 Cool Things About SQL
5 Cool Things About SQL
 

More from Karen Morton

Managing SQL Performance
Managing SQL PerformanceManaging SQL Performance
Managing SQL PerformanceKaren Morton
 
The Oracle Advisors from a Different Perspective
The Oracle Advisors from a Different PerspectiveThe Oracle Advisors from a Different Perspective
The Oracle Advisors from a Different PerspectiveKaren Morton
 
Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceKaren Morton
 
Performance Instrumentation for PL/SQL: When, Why, How
Performance Instrumentation for PL/SQL: When, Why, HowPerformance Instrumentation for PL/SQL: When, Why, How
Performance Instrumentation for PL/SQL: When, Why, HowKaren Morton
 
zen and the art of SQL optimization
zen and the art of SQL optimizationzen and the art of SQL optimization
zen and the art of SQL optimizationKaren Morton
 
Are you a monkey or an astronaut?
Are you a monkey or an astronaut?Are you a monkey or an astronaut?
Are you a monkey or an astronaut?Karen Morton
 

More from Karen Morton (6)

Managing SQL Performance
Managing SQL PerformanceManaging SQL Performance
Managing SQL Performance
 
The Oracle Advisors from a Different Perspective
The Oracle Advisors from a Different PerspectiveThe Oracle Advisors from a Different Perspective
The Oracle Advisors from a Different Perspective
 
Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
 
Performance Instrumentation for PL/SQL: When, Why, How
Performance Instrumentation for PL/SQL: When, Why, HowPerformance Instrumentation for PL/SQL: When, Why, How
Performance Instrumentation for PL/SQL: When, Why, How
 
zen and the art of SQL optimization
zen and the art of SQL optimizationzen and the art of SQL optimization
zen and the art of SQL optimization
 
Are you a monkey or an astronaut?
Are you a monkey or an astronaut?Are you a monkey or an astronaut?
Are you a monkey or an astronaut?
 

Recently uploaded

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 

Recently uploaded (20)

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 

Managing Statistics for Optimal Query Performance

  • 1. Managing Statistics for Optimal Query Performance Karen Morton karen.morton@agilex.com OOW 2009 2009 October 13 1:00pm-2:00pm Moscone South Room 305
  • 2. Your speaker… •Karen Morton – Sr. Principal Database Engineer – Educator, DBA, developer, consultant, researcher, author, speaker, … •Come see me… – karenmorton.blogspot.com – An Oracle user group near you
  • 3. Math or Magic ?
  • 4. “I accept no responsibility for statistics, which are a form of magic beyond my comprehension.” — Robertson Davies
  • 5. SQL>desc deck Name Null? Type ------------- -------- ------------- SUIT NOT NULL VARCHAR2(10) CARD VARCHAR2(10) COLOR VARCHAR2(5) FACEVAL NOT NULL NUMBER(2)
  • 6. Table: DECK Statistic Current value --------------- ------------------- # rows 52 Blocks 5 Avg Row Len 20 Degree 1 Sample Size 52 Column Name NDV Nulls # Nulls Density Length Low Value High Value ----------- --- ----- ------- ------- ------ ---------- ----------- SUIT 4 N 0 .250000 8 Clubs Spades CARD 13 Y 0 .076923 5 Ace Two COLOR 2 Y 0 .500000 5 Black Red FACEVAL 13 N 0 .076923 3 1 13 Index Name Col# Column Name Unique? Height Leaf Blks Distinct Keys -------------- ----- ------------ ------- ------ ---------- ------------- DECK_PK 1 SUIT Y 1 1 52 2 FACEVAL DECK_CARD_IDX 1 CARD N 1 1 13 DECK_COLOR_IDX 1 COLOR N 1 1 2
  • 7. Cardinality The estimated number of rows a query is expected to return. number of rows in table x predicate selectivity
  • 8. select * from deck order by suit, faceval ; Cardinality 52 x 1 = 52
  • 9. SQL>select * from deck order by suit, faceval ; 52 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 3142028678 ---------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 52 | 1040 | 2| | 1 | TABLE ACCESS BY INDEX ROWID| DECK | 52 | 1040 | 2| | 2 | INDEX FULL SCAN | DECK_PK | 52 | | 1| ---------------------------------------------------------------------- *
  • 10. select * from deck where color = 'Black' ; Cardinality 52 x 1/2 = 26
  • 11. SQL>select * from deck where color = 'Black' ; 26 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 1366616955 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 26 | 520 | 2| | 1 | TABLE ACCESS BY INDEX ROWID| DECK | 26 | 520 | 2| |* 2 | INDEX RANGE SCAN | DECK_COLOR_ID | 26 | | 1| ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("COLOR"='Black')
  • 12. select * from deck where card = 'Ace' and suit = 'Spades' ; Cardinality 52 x 1/13 x 1/4 = 1
  • 13. SQL>select * 2 from deck 3 where card = 'Ace' 4 and suit = 'Spades' ; 1 row selected. Execution Plan ---------------------------------------------------------- Plan hash value: 2030372774 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 2| |* 1 | TABLE ACCESS BY INDEX ROWID| DECK | 1 | 20 | 2| |* 2 | INDEX RANGE SCAN | DECK_CARD_IDX | 4 | | 1| ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("SUIT"='Spades') 2 - access("CARD"='Ace')
  • 14. select * from deck where faceval > 10 ; Cardinality (13 – 10) High Value - Predicate Value 52 x (13 – 1) High Value - Low Value = 13
  • 15. SQL>select * 2 from deck 3 where faceval > 10 ; 12 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 1303963799 --------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | --------------------------------------------------------- | 0 | SELECT STATEMENT | | 13 | 260 | 3| |* 1 | TABLE ACCESS FULL| DECK | 13 | 260 | 3| --------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("FACEVAL">10)
  • 16. select * from deck where card = 'Ace' ; Cardinality 52 x 1/13 = 4
  • 17. SQL>select * from deck where card = :b1 ; 4 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 2030372774 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 4 | 80 | 2| | 1 | TABLE ACCESS BY INDEX ROWID| DECK | 4 | 80 | 2| |* 2 | INDEX RANGE SCAN | DECK_CARD_IDX | 4 | | 1| ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("CARD"=:B1)
  • 18. Math or Magic ? Maybe it's a little bit of both!
  • 19. What's the best method for collecting statistics?
  • 21. Statistics that don't reasonably describe your data
  • 23. …which leads to poor access path selection
  • 24. …which leads to poor join method selection
  • 25. …which leads to poor join order selection
  • 26. …which leads to poor SQL execution times.
  • 28. Automatic vs Manual
  • 30. Objects must change by at least 10%
  • 31. Collection scheduled during nightly maintenance window
  • 33. Prioritizes collection in order by objects which most need updating
  • 34. Most functional when data changes at a slow to moderate rate
  • 35. Volatile tables and large bulk loads are good candidates for manual collection
  • 36. Automatic doesn't mean accurate (for your data)
  • 38. SQL>exec dbms_stats.gather_table_stats (ownname=>?, tabname=>?) ; partname NULL cascade DBMS_STATS.AUTO_CASCADE estimate_percent DBMS_STATS.AUTO_SAMPLE_SIZE stattab NULL block_sample FALSE statid NULL method_opt FOR ALL COLUMNS SIZE AUTO statown NULL degree 1 or value based on number of CPUs and initialization parameters force FALSE granularity AUTO (value is based on partitioning type) no_invalidate DBMS_STATS.AUTO_INVALIDATE
  • 39. cascade=> AUTO_CASCADE Allow Oracle to determine whether or not to gather index statistics
  • 41. method_opt=> FOR ALL COLUMNS SIZE AUTO Allow Oracle to determine when to gather histogram statistics SYS.COL_USAGE$
  • 42. no_invalidate=> AUTO_INVALIDATE Allow Oracle to determine when to invalidate dependent cursors
  • 43. Goal Collect statistics that are "good enough" to meet most needs most of the time.
  • 44. Say you were standing with one foot in the oven and one foot in an ice bucket. According to the percentage people, you would be perfectly comfortable. – Bobby Bragan
  • 46. dbms_stats gather_*_stats * = database, schema, table, index, etc.
  • 47. Is it common for your users to get slammed with performance problems shortly after statistics are updated?
  • 48. Does performance decline before a 10% data change occurs?
  • 49. Do low and high values for a column change significantly between automatic collections?
  • 50. Does your application performance seem "sensitive" to changing user counts as well as data volume changes?
  • 51. If you answered "Yes" to one or more of these questions...
  • 52. your application's unique needs may be best served with manual collection.
  • 55. optimizer_dynamic_sampling parameter dynamic_sampling hint
  • 56. SQL>create table depend_test as 2 select mod(num, 100) c1, 3 mod(num, 100) c2, 4 mod(num, 75) c3, 5 mod(num, 30) c4 6 from (select level num from dual 7 connect by level <= 10001); Table created. SQL>exec dbms_stats.gather_table_stats( user, 'depend_test', estimate_percent => null, method_opt => 'for all columns size 1'); PL/SQL procedure successfully completed.
  • 57. Statistic Current value --------------- -------------- # rows 10001 Blocks 28 Avg Row Len 11 Sample Size 10001 Monitoring YES Column NDV Density AvgLen Histogram LowVal HighVal ------- --- ------- ------ --------- ------ ------- C1 100 .010000 3 NONE (1) 0 99 C2 100 .010000 3 NONE (1) 0 99 C3 75 .013333 3 NONE (1) 0 74 C4 30 .033333 3 NONE (1) 0 29
  • 58. SQL>set autotrace traceonly explain SQL>select count(*) from depend_test where c1 = 10; Execution Plan ---------------------------------------------------------- Plan hash value: 3984367388 ---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 3 | 8 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | |* 2 | TABLE ACCESS FULL| DEPEND_TEST | 100 | 300 | 8 (0)| 00:00:01 | ---------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("C1"=10)
  • 59. SQL>set autotrace traceonly explain SQL>select count(*) from depend_test where c1 = 10 and c2 = 10; Execution Plan ---------------------------------------------------------- Plan hash value: 3984367388 ---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 | 8 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 6 | | | |* 2 | TABLE ACCESS FULL| DEPEND_TEST | 1 | 6 | 8 (0)| 00:00:01 | ---------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("C1"=10 AND "C2"=10)
  • 60. SQL>set autotrace traceonly explain SQL>select /*+ dynamic_sampling (4) */ count(*) 2 from depend_test where c1 = 10 and c2 = 10; Execution Plan ---------------------------------------------------------- Plan hash value: 3984367388 ---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 | 8 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 6 | | | |* 2 | TABLE ACCESS FULL| DEPEND_TEST | 100 | 600 | 8 (0)| 00:00:01 | ---------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("C1"=10 AND "C2"=10) Note ----- - dynamic sampling used for this statement
  • 62. SQL> select dbms_stats.create_extended_stats(ownname=>user, 2 tabname => 'DEPEND_TEST', 3 extension => '(c1, c2)' ) AS c1_c2_correlation 4 from dual ; C1_C2_CORRELATION ------------------------------------------------------------- SYS_STUF3GLKIOP5F4B0BTTCFTMX0W SQL> exec dbms_stats.gather_table_stats( user, 'depend_test'); PL/SQL procedure successfully completed.
  • 63. SQL> set autotrace traceonly explain SQL> select count(*) from depend_test where c1 = 10 and c2 = 10; Execution Plan ---------------------------------------------------------- Plan hash value: 3984367388 ---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 | 9 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 6 | | | |* 2 | TABLE ACCESS FULL| DEPEND_TEST | 100 | 600 | 9 (0)| 00:00:01 | ---------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("C1"=10 AND "C2"=10)
  • 67. Why guess (i.e. gather stats) when you know!
  • 69. 3 areas where non-representative statistics cause problems
  • 70. 1 Data Skew
  • 71. The optimizer assumes uniform distribution of column values.
  • 72. Color column - uniform distribution
  • 73. Color column – skewed distribution
  • 74. Data skew must be identified with a histogram.
  • 75. Table: obj_tab 100% Statistics Statistic Current value FOR ALL COLUMNS SIZE 1 --------------- -------------- # rows 1601874 Blocks 22321 Avg Row Len 94 Sample Size 1601874 Monitoring YES Column: object_type (has 36 distinct values) OBJECT_TYPE PCT_TOTAL ------------------------------- --------- WINDOW GROUP - PROGRAM .00-.02 EVALUATION CONTEXT - XML SCHEMA .03-.05 OPERATOR - PROCEDURE .11-.17 LIBRARY - TYPE BODY .30-.35 FUNCTION - INDEX PARTITION .54-.64 JAVA RESOURCE - PACKAGE 1.54-1.69 TABLE - VIEW 3.44-7.35 JAVA CLASS 32.80 SYNONYM 40.01
  • 76. PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- SQL_ID 16yy3p8sstr28, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id, status from obj_tab where object_type = 'PROCEDURE' Plan hash value: 2862749165 -------------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | -------------------------------------------------------------------------------- | 1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB | 44497 | 2720 | 1237 | |* 2 | INDEX RANGE SCAN | OBJ_TYPE_IDX | 44497 | 2720 | 193 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"='PROCEDURE') E-Rows = 1/36 x 1,601,874 R = .06 seconds
  • 77. PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- SQL_ID 9u6ppkh5mhr8v, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id, status from obj_tab where object_type = 'SYNONYM' Plan hash value: 2862749165 -------------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | -------------------------------------------------------------------------------- | 1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB | 44497 | 640K| 104K| |* 2 | INDEX RANGE SCAN | OBJ_TYPE_IDX | 44497 | 640K| 44082 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"='SYNONYM') E-Rows = 1/36 x 1,601,874 R = 14.25 seconds
  • 78. Re-collect statistics 100% FOR ALL COLUMNS SIZE AUTO
  • 79. PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- SQL_ID 16yy3p8sstr28, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id, status from obj_tab where object_type = 'PROCEDURE' Plan hash value: 2862749165 -------------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | -------------------------------------------------------------------------------- | 1 | TABLE ACCESS BY INDEX ROWID| OBJ_TAB | 2720 | 2720 | 1237 | |* 2 | INDEX RANGE SCAN | OBJ_TYPE_IDX | 2720 | 2720 | 193 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"='PROCEDURE') E-Rows = histogram x 1,601,874 R = .07 seconds
  • 80. PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- SQL_ID 9u6ppkh5mhr8v, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ owner, object_name, object_type, object_id, status from obj_tab where object_type = 'SYNONYM' Plan hash value: 2748991475 ----------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | ----------------------------------------------------------------- |* 1 | TABLE ACCESS FULL| OBJ_TAB | 640K| 640K| 64263 | ----------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_TYPE"='SYNONYM') E-Rows = histogram x 1,601,874 R = 3.36 seconds vs 14.25 seconds
  • 81. Histograms are important for more reasons than just helping determine the access method.
  • 82. 2 Bind Peeking
  • 83. During hard parse, the optimizer "peeks" at the bind value and uses it to determine the execution plan.
  • 84. But, what if your data is skewed? 11g
  • 85. SQL> variable objtype varchar2(19) SQL> exec :objtype := 'PROCEDURE'; PL/SQL procedure successfully completed. SQL> select /*+ gather_plan_statistics */ count(*) ct 2 from big_tab 3 where object_type = :objtype ; CT --------------- 4416 1 row selected. SQL> SQL> select * from table (dbms_xplan.display_cursor('211078a9adzak',0,'ALLSTATS LAST'));
  • 86. PLAN_TABLE_OUTPUT --------------------------------------- SQL_ID 211078a9adzak, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ count(*) ct from big_tab where object_type = :objtype Plan hash value: 154074842 ------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 16 | |* 2 | INDEX RANGE SCAN| BIG_OBJTYPE_IDX | 4416 | 4416 | 16 | ------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"=:OBJTYPE)
  • 87. SQL> select child_number, executions, buffer_gets, 2 is_bind_sensitive, is_bind_aware, is_shareable 3 from v$sql where sql_id = '211078a9adzak' ; CHILD_NUMBER = 0 EXECUTIONS = 1 BUFFER_GETS = 16 IS_BIND_SENSITIVE = N IS_BIND_AWARE = N IS_SHAREABLE = Y
  • 88. SQL> variable objtype varchar2(19) SQL> exec :objtype := 'SYNONYM'; PL/SQL procedure successfully completed. SQL> select /*+ gather_plan_statistics */ count(*) ct 2 from big_tab 3 where object_type = :objtype ; CT ---------------- 854176 1 row selected. SQL> SQL> select * from table (dbms_xplan.display_cursor('211078a9adzak',0,'ALLSTATS LAST'));
  • 89. PLAN_TABLE_OUTPUT --------------------------------------- SQL_ID 211078a9adzak, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ count(*) ct from big_tab where object_type = :objtype Plan hash value: 154074842 ------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 2263 | |* 2 | INDEX RANGE SCAN| BIG_OBJTYPE_IDX | 4416 | 854K | 2263 | ------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"=:OBJTYPE)
  • 90. SQL> select child_number, executions, buffer_gets, 2 is_bind_sensitive, is_bind_aware, is_shareable 3 from v$sql where sql_id = '211078a9adzak' ; CHILD_NUMBER = 0 EXECUTIONS = 2 BUFFER_GETS = 2279 (2263 + 16) IS_BIND_SENSITIVE = Y IS_BIND_AWARE = N IS_SHAREABLE = Y
  • 91. SQL> variable objtype varchar2(19) SQL> exec :objtype := 'SYNONYM'; PL/SQL procedure successfully completed. PLAN_TABLE_OUTPUT --------------------------------------- SQL_ID 211078a9adzak, child number 1 ------------------------------------- select /*+ gather_plan_statistics */ count(*) ct from big_tab where object_type = :objtype Plan hash value: 1315022418 ----------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | ----------------------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 6016 | |* 2 | INDEX FAST FULL SCAN| BIG_OBJTYPE_IDX | 854K | 854K | 6016 | ----------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"=:OBJTYPE)
  • 92. SQL> select child_number, executions, buffer_gets, 2 is_bind_sensitive, is_bind_aware, is_shareable 3 from v$sql where sql_id = '211078a9adzak' ; CHILD_NUMBER = 0 CHILD_NUMBER = 1 EXECUTIONS = 2 EXECUTIONS = 1 BUFFER_GETS = 2279 BUFFER_GETS = 6016 IS_BIND_SENSITIVE = Y IS_BIND_SENSITIVE = Y IS_BIND_AWARE = N IS_BIND_AWARE = Y IS_SHAREABLE = N IS_SHAREABLE = Y
  • 93. SQL> variable objtype varchar2(19) SQL> exec :objtype := 'PROCEDURE'; PL/SQL procedure successfully completed. PLAN_TABLE_OUTPUT --------------------------------------- SQL_ID 211078a9adzak, child number 2 ------------------------------------- select /*+ gather_plan_statistics */ count(*) ct from big_tab where object_type = :objtype Plan hash value: 154074842 ------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 16 | |* 2 | INDEX RANGE SCAN| BIG_OBJTYPE_IDX | 4416 | 4416 | 16 | ------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"=:OBJTYPE)
  • 94. SQL> select child_number, executions, buffer_gets, 2 is_bind_sensitive, is_bind_aware, is_shareable 3 from v$sql where sql_id = '211078a9adzak' ; CHILD_NUMBER = 0 CHILD_NUMBER = 1 EXECUTIONS = 2 EXECUTIONS = 1 BUFFER_GETS = 2279 BUFFER_GETS = 6016 IS_BIND_SENSITIVE = Y IS_BIND_SENSITIVE = Y IS_BIND_AWARE = N IS_BIND_AWARE = Y IS_SHAREABLE = N IS_SHAREABLE = Y CHILD_NUMBER = 2 EXECUTIONS = 1 BUFFER_GETS = 16 IS_BIND_SENSITIVE = Y IS_BIND_AWARE = Y IS_SHAREABLE = Y
  • 95. 10g will create only 1 plan. 11g will create plans as needed to cover data skew.
  • 96. Handling bind peeking is more of a coding issue than a statistics issue.
  • 97. 3 Incorrect High and Low Values
  • 98. To derive the cardinality estimate for range predicates, the optimizer uses the low and high value statistics.
  • 99. Table: hi_lo_t Statistic Current value --------------- --------------------- # rows 100000 Blocks 180 Avg Row Len 7 Sample Size 100000 Monitoring YES Column NDV Nulls Density AvgLen Histogram LowVal HighVal ------- ------ ----- ------- ------ --------- ------ ------- A 100000 N .000010 5 NONE (1) 10 100009 B 10 Y .100000 3 NONE (1) 9 18 100% Statistics FOR ALL COLUMNS SIZE 1
  • 100. select count(a) from hi_lo_t where b < 11 ; ( 11 – 9 18 – 9 ) Predicate value – Low value High value – Low value 100000 rows x .22222 = 22222
  • 101. select count(a) from hi_lo_t where b < 11 Plan hash value: 3307858660 ------------------------------------------------------------------ | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------ | 1 | SORT AGGREGATE | | 1 | 1 | 184 | |* 2 | TABLE ACCESS FULL| HI_LO_T | 22222 | 20000 | 184 | ------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("B"<11)
  • 102. select count(a) from hi_lo_t where b < 4 ; .10 x ( 1 + 4 – 9 18 – 9 ) Predicate value – Low value High value – Low value 100000 rows x .04444 = 4444
  • 103. select count(a) from hi_lo_t where b < 4 Plan hash value: 3307858660 ------------------------------------------------------------------ | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------ | 1 | SORT AGGREGATE | | 1 | 1 | 184 | |* 2 | TABLE ACCESS FULL| HI_LO_T | 4444 | 0 | 184 | ------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("B"<4)
  • 104. METHOD_OPT=> 'FOR ALL INDEXED COLUMNS' Be cautious of using this!
  • 105. If column is not indexed, no statistics are collected.
  • 106. select count(a) from hi_lo_t where b = 12 Plan hash value: 3307858660 ------------------------------------------------------------------ | Id | Operation | Name | E-Rows | A-Rows | Buffers | ------------------------------------------------------------------ | 1 | SORT AGGREGATE | | 1 | 1 | 184 | |* 2 | TABLE ACCESS FULL| HI_LO_T | 1000 | 10000 | 184 | ------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("B"=12) Without statistics, a 10% default is used.
  • 107. Result: Cardinality estimates that are orders of magnitude "off"
  • 109. Why guess when you can know.
  • 110. Thoroughly test and document your statistics collection strategy.
  • 111. Check default options particularly when upgrading. Things change.
  • 112. Regularly check statistics and compare to previous collections for any anomalies. 10.2.0.4 and above dbms_stats.diff_table_stats_*
  • 114. There is no single strategy that works best for everyone.
  • 116. Understanding basic optimizer statistics computations is key.
  • 117. The more you know, the more likely you are to succeed.
  • 119. Q U E S T I O N S A N S W E R S