SlideShare ist ein Scribd-Unternehmen logo
1 von 360
Downloaden Sie, um offline zu lesen
NOTE

     itty bitty fonts in this
           presentation


               SQL> exec sample_font




Can you read this ?
                                       1
Connor McDonald
    OracleDBA



                co.uk




                        2
3
bio slide




            4
Connor McDonald
a funny story




                6
7
8
9
why ?

        10
12
life was simple




                  14
15
(good) cost optimizer




                        16
17
version 7.0




              18
optimizer_mode = CHOOSE




                          19
"we choose RULE"




                   20
SQL> analyze table SALES estimate statistics;




                                                21
22
eventually....




                 23
it got better




                24
added more functionality




                           25
SQL> analyze table SALES estimate statistics
  2     for table
  3     for columns size 10
  4     for ....;




                                               26
SQL syntax engine




                    27
oracle 8i




            28
DBMS_STATS




             29
problem....




              30
SQL> analyze table SALES estimate statistics;




                          41 characters

                                                31
SQL> begin
  2    dbms_stats.gather_table_stats(
  3      ownname=>'HR',
  4      tabname=>'SALES',
  5      cascade=>true,
  6      estimate_percent=>20
  7      );
  8 end;
                    128 characters

                                        32
don't get chaining




                     33
s l o w e r




              34
"I don't think so....."




                          35
times have changed ...




                         36
SQL> desc DBMS_STATS

PROCEDURE ALTER_DATABASE_TAB_MONITORING
PROCEDURE ALTER_SCHEMA_TAB_MONITORING
PROCEDURE ALTER_STATS_HISTORY_RETENTION
PROCEDURE CLEANUP_STATS_JOB_PROC
PROCEDURE CONVERT_RAW_VALUE
PROCEDURE CONVERT_RAW_VALUE
PROCEDURE CONVERT_RAW_VALUE
PROCEDURE CONVERT_RAW_VALUE
PROCEDURE CONVERT_RAW_VALUE
PROCEDURE CONVERT_RAW_VALUE_NVARCHAR
PROCEDURE CONVERT_RAW_VALUE_ROWID
PROCEDURE COPY_TABLE_STATS
FUNCTION CREATE_EXTENDED_STATS RETURNS VARCHAR
PROCEDURE CREATE_STAT_TABLE
PROCEDURE DELETE_COLUMN_STATS               37
126 routines !




                 38
39
profiles

                             tuning sets


baselines

                       features

     bind peeking

                           adaptive cursor sharing


                                                     40
better stats needed ...




                          41
... for the optimizer




                        42
hard to convince




                   43
44
stop using analyze




                     45
ego




      46
"good ol' days"




                  47
48
49
today....




            50
optimizer is probably...




                           51
... smarter than you




                       52
nested loop outer
                            sort merge outer


     SQL>   select   count(e.hiredate)
       2    from     DEPT d, EMP e
       3    where    e.deptno = d.deptno(+)
       4    and      e.sal > 10;

       hash                        hash anti

                       nested loop anti
53
-------------------------------------------
     | Id | Operation           | Name | Rows |
     -------------------------------------------
     |   0 | SELECT STATEMENT   |      |     1 |
     |   1 | SORT AGGREGATE     |      |     1 |
     |* 2 |    TABLE ACCESS FULL| EMP |     14 |
     -------------------------------------------



                                  no DEPT ?

54
not null


     SQL>   select   count(e.hiredate)
       2    from     DEPT d, EMP e
       3    where    e.deptno = d.deptno(+)
       4    and      e.sal > 10;




                                foreign key
55                              key preserved
Oracle's solution....




                        56
statistics by stealth...




                           57
10g




      58
SQL> select owner, job_name, enabled
  2 from    dba_scheduler_jobs
  3 where owner = 'SYS';

OWNER             JOB_NAME                         ENABLED
---------------   ------------------------------   -------
SYS               PURGE_LOG                        TRUE
SYS               FGR$AUTOPURGE_JOB                TRUE
SYS               GATHER_STATS_JOB                 FALSE
                                                   TRUE
SYS               AUTO_SPACE_ADVISOR_JOB           TRUE




 59
11g




      60
SQL> select owner, job_name, enabled
  2 from    dba_scheduler_jobs
  3 where owner = 'SYS';

OWNER             JOB_NAME                         ENABLED
---------------   ------------------------------   -------
SYS               AUTO_SPACE_ADVISOR_JOB           FALSE
SYS               BSLN_MAINTAIN_STATS_JOB          TRUE
SYS               DRA_REEVALUATE_OPEN_FAILURES     TRUE
SYS               FGR$AUTOPURGE_JOB                FALSE
SYS               GATHER_STATS_JOB                 FALSE
SYS               HM_CREATE_OFFLINE_DICTIONARY     FALSE
SYS               ORA$AUTOTASK_CLEAN               TRUE
SYS               PURGE_LOG                        TRUE
SYS               XMLDB_NFS_CLEANUP_JOB            FALSE


 61
stats STILL being collected




                              62
automatic "tasks"


        "super stealth mode"


                               63
SQL> select client_name, status
       2 from    DBA_AUTOTASK_CLIENT;

     CLIENT_NAME                            STATUS
     ------------------------------------   --------
     auto optimizer stats collection        ENABLED
     auto space advisor                     ENABLED
     sql tuning advisor                     ENABLED




64
stats every night


    most sites


 default options


                    65
in this session...




                     66
default behaviour




                    67
BAD
IDEA   68
collecting statistics




                        69
BAD
IDEA   70
but....




          71
some default behaviour




                         72
GOOD
IDEA   73
collecting some statistics




                             74
GOOD
IDEA   75
76
Inflammatory
 statements
  which will
 alienate the
  audience



                1




                    Presentation Duration



                                            77
we're all hypocrites




                       78
statistical hypocrisy




                        79
"I need to change some
reference data in my system"




                               80
wrong case
"nope...."




             82
ITIL
       83
Information

 Technology

Infrastructure

   Library

                 84
service
  call
          help
          desk   DONE !
                    problem
                     record
phew....




           86
corrected
same site....




                88
"Every night, I would like to
    potentially change the
performance characteristics of
 every single SQL statement in
         the database"



                                  89
"no problem...."




                   90
collecting stats = risk




                          91
Ensor's paradox




                  92
1987

performance group

   bstat/estat

     tkprof

   BMC patrol

    afiedt.buf




                    93
"It is only safe to
gather statistics ..."


"...when to do so will
make no difference"


                         94
recommendation #1




                    95
96
unless things are bad...

do not change statistics




                           97
"surely it can't hurt?"




                          98
10g




      99
options=>'GATHER STALE'




                          100
options=>'GATHER EMPTY'




                          101
options=>'GATHER AUTO'




                         102
"no plans changed"




                     103
"no queries ran slower"




                          104
still problems




                 105
problem # 1




              106
dbms_stats




             107
the goal of statistics




                         108
minimise expensive SQL....




                             109
added more expensive SQL !




                             110
SQL> alter session set sql_true = true;

Session altered.

SQL> begin
  2    dbms_stats.gather_table_stats(
  3      'DEMO',
  4      'PEOPLE);
  5 end;
  6 /




                                          111
SQL> select
  2    count(distinct GENDER),
  3    min(GENDER),
  4    max(GENDER),
  5    count(distinct NAME),
  6    min(NAME),
  7    max(NAME)
       ...
       ...
 21 from PEOPLE;




                                 112
hard !




         113
problem #2




             115
lingering pain




                 116
invalidation




               117
library cache




                119
select *                             insert into PEOPLE
from   PEOPLE                        select * from ...
                  select ...
                  from   PEOPLE,
                         DEPT
                  where ...

       SQL> begin
         2    dbms_stats.gather_table_stats(
         3      'DEMO',
         4      'PEOPLE);
         5 end;
         6 /
                              declare
  delete from T                  v people.name%type;
  where X in                  begin
    ( select PID                 ...
      from   PEOPLE )



                                                          120
121
recap




        122
gathering statistics

   really hard core SQL

     belted CPU with hard parsing

          everything ran the same


                                    123
oracle 9




           124
SQL> desc DBMS_STATS

PROCEDURE GATHER_TABLE_STATS
 Argument Name           Type             In/Out   Default?
 ----------------------- --------------   ------   --------
 OWNNAME                 VARCHAR2         IN
 TABNAME                 VARCHAR2         IN
 PARTNAME                VARCHAR2         IN       DEFAULT
 ESTIMATE_PERCENT        NUMBER           IN       DEFAULT
 BLOCK_SAMPLE            BOOLEAN          IN       DEFAULT
 METHOD_OPT              VARCHAR2         IN       DEFAULT
 DEGREE                  NUMBER           IN       DEFAULT
 GRANULARITY             VARCHAR2         IN       DEFAULT
 CASCADE                 BOOLEAN          IN       DEFAULT
 STATTAB                 VARCHAR2         IN       DEFAULT
 STATID                  VARCHAR2         IN       DEFAULT
 STATOWN                 VARCHAR2         IN       DEFAULT
 NO_INVALIDATE           BOOLEAN          IN       DEFAULT
 STATTYPE                VARCHAR2         IN       DEFAULT
 FORCE                   BOOLEAN          IN       DEFAULT


                                                              125
?
no_invalidate => false | true



                   ?
                                126
oracle 10




            127
no_invalidate => auto




                        128
SQL> select
  2    x.ksppinm     name,
  3    y.kspftctxvl value
  4 from
  5      sys.x$ksppi x,
  6      sys.x$ksppcv2 y
  7 where
  8      x.indx+1 = y.kspftctxpn and
  9      x.ksppinm = '_optimizer_invalidation_period'

NAME                           VALUE
------------------------------ ------------
_optimizer_invalidation_period 18000




                                                        129
select *                           insert into PEOPLE
from   PEOPLE                      select * from ...


                select ...
                from   PEOPLE,
                       DEPT
                where ...


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

                                 declare
  delete from T                     v people.name%type;
  where X in                     begin
    ( select PID                    ...
      from   PEOPLE )



                                                          130
better ?




           131
hard parse storm avoided




                           132
5 hours before problems




                          133
134
unless things are bad...

DO NOT CHANGE STATISTICS




                            135
Inflammatory
 statements
  which will
 alienate the
  audience
                2



                1




                    Presentation Duration



                                            136
we don't know if things are bad




                                  137
until its too late




                     138
users fed up



     SQL's are slow



           stats out of date

                               139
140
141
2 hours to gather stats




                          142
143
collect stats




                144
in readiness




               145
146
pending statistics




                     147
"published" – optimizer uses

   "pending" - private




                               148
SQL> begin
  2     dbms_stats.set_schema_prefs(
  3         ownname=>'DEMO',
  4         pname=>'PUBLISH',
  5         pvalue=>'FALSE');
  6 end;

                            database,
                              table
                                        149
SQL> alter session set
  2     optimizer_use_pending_statistics = true;




                                               150
SQL> begin
  2     dbms_stats.publish_pending_stats(
  3         ownname=>'DEMO',
  4         tabname=>null);
  5 end;




                                            151
recommendation #2




                    152
when collecting statistics




                             153
PUBLISH = false


             always....

                          154
even if you immediately publish




                                  155
atomic publication




                     156
and don't wait 5 hours




                         157
_optimizer_invalidation_period




                                 158
for most tables




                  159
dbms_stats.lock_table_stats




                              160
collecting system stats




                          161
different story




                  162
absolutely vital…


      …to have them

                      163
maximize I/O throughput




164
SQL> set autotrace traceonly explain
      SQL> select * from T;

      ---------------------------------------------------------------
      | Id | Operation          | Name | Rows | Bytes | Cost (%CPU)|
      ---------------------------------------------------------------
      |   0 | SELECT STATEMENT |       | 53459 | 4489K|    113   (1)|
      |   1 | TABLE ACCESS FULL| T     | 53459 | 4489K|    113   (1)|
      ---------------------------------------------------------------

      SQL> select value
        2 from    v$spparameter
        3 where name = 'db_file_multiblock_read_count';

      VALUE
      -----------
      16




165
SQL> alter session set events
        2     = '10046 trace name context forever, level 8';
      SQL> select * from T;

      PARSING IN CURSOR #22 len=15 dep=0 uid=124 oct=3 lid=124 ...
      select * from T
      END OF STMT
      PARSE #22:c=10000,e=108,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4
      EXEC #22:c=0,e=65,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4

      WAIT #22: nam='db file scattered read' ela= 3387
         file#=5 block#=13122 blocks=16 obj#=199963

      WAIT #22: nam='db file scattered read' ela= 3188
         file#=5 block#=13234 blocks=16 obj#=199963

      WAIT #22: nam='db file scattered read' ela= 3125
         file#=5 block#=13250 blocks=16 obj#=199963

      WAIT #22: nam='db file scattered read' ela= 3255
         file#=5 block#=13266 blocks=16 obj#=199963

      WAIT #22: nam='db file scattered read' ela= 3369
         file#=5 block#=13282 blocks=16 obj#=199963
166
SSTIOMAX




167
1 MB




168
db_block_size = 8192




169
db_file_multiblock_read_count = 128




170
?

171
172
the solution ?




173
system stats




174
SQL> select pname, pval1
        2 from sys.aux_stats$
        3 /

      PNAME                               PVAL1
      ------------------------------ ----------
      SREADTIM                            4.065
      MREADTIM                            6.173
      CPUSPEED                              567
      MBRC                                   12
      MAXTHR                           48203776
      SLAVETHR                               -1




175
use MBRC to cost




176
use db_file_multiblock_read_count to read




177
Inflammatory
 statements 3
  which will
 alienate the
  audience
           2



           1




                Presentation Duration



                                        178
forget about system statistics




                                 179
do not use them




                  180
181
182
absolutely vital…


      …to have them

                      183
do not “use”* them


    * = collect, change, set

                               184
problem #1




             185
186
problem #2




             187
monitoring for bad....




                         188
optimizing for bad




                     189
recommendation #3




                    190
gather



    into STAT table

                      191
monitor




          192
set once




           193
the defaults are probably fine




                                 194
SQL> select pname, pval1
        2 from sys.aux_stats$
        3 /

      PNAME                       PVAL1
      ---------------------- ----------
      IOSEEKTIM                      10          (ms)
      IOTFRSPEED                   4096          (bytes/ms)


      SREADTIM = IOSEEKTIM + db_block_size / IOTFRSPEED = 10

      MREADTIM = IOSEEKTIM + mbrc * db_block_size / IOTFRSPEED = 26




195
10.2 and above




                 196
_db_file_optimizer_read_count



db_file_multiblock_read_count


    _db_file_exec_read_count


                                  197
dbms_resource_manager


             to calibrate

                            198
so far...




            199
not changing statistics




                          200
eventually....




                 201
the time will come...




                        202
one possible reason




                      203
even if stats unchanged …




                            204
… your plans might !




                       205
SQL>   create table T as
  2    select to_date('01-AUG-2011')+
  3              trunc(dbms_random.value(0,7)) dte,
  4           rpad('padding',20) padding
  5    from dual
  6    connect by level <= 100000;

Table created.
SQL>   select dte, count(*)
  2    from   t
  3    group by dte
  4    order by 1;

DTE         COUNT(*)
--------- ----------
01-AUG-11      14334
02-AUG-11      14222
03-AUG-11      14167
04-AUG-11      14510
05-AUG-11      14346
06-AUG-11      14349
07-AUG-11      14072
15,000 rows per day always




                             208
SQL> exec dbms_stats.gather_table_stats(user,'T')

PL/SQL procedure successfully completed.

SQL> create index IX on T ( dte ) ;

Index created.
SQL> select * from t where dte = '03-AUG-2011';

--------------------------------------------------
| Id | Operation          | Name | Rows | Bytes |
--------------------------------------------------
|   0 | SELECT STATEMENT |       | 14286 |   404K|
|* 1 | TABLE ACCESS FULL| T      | 14286 |   404K|
--------------------------------------------------
a week later…




                211
SQL>   insert into T
  2    select to_date('08-AUG-2011')+
  3              trunc(dbms_random.value(0,7)) dte,
  4           rpad('padding',20) padding
  5    from dual
  6    connect by level <= 100000;

100000 rows created.
SQL>   select dte, count(*)
  2    from   t
  3    group by dte
  4    order by 1;

DTE         COUNT(*)
--------- ----------
01-AUG-11      14334
  ...
07-AUG-11      14072
08-AUG-11      14261
09-AUG-11      14106
10-AUG-11      14410
11-AUG-11      14289
12-AUG-11      14358
13-AUG-11      14252
14-AUG-11      14324
statistics unchanged




                       214
SQL> select * from t where dte = '12-AUG-2011';

----------------------------------------------------
| Id | Operation                    | Name | Rows |
----------------------------------------------------
|   0 | SELECT STATEMENT            |      | 2381 |
|   1 | TABLE ACCESS BY INDEX ROWID| T     | 2381 |
|* 2 |    INDEX RANGE SCAN          | IX   | 2381 |
----------------------------------------------------
SQL> select * from t where dte = '14-AUG-2011';

----------------------------------------------------
| Id | Operation                    | Name | Rows |
----------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |
|   1 | TABLE ACCESS BY INDEX ROWID| T     |     1 |
|* 2 |    INDEX RANGE SCAN          | IX   |     1 |
----------------------------------------------------
why ?




        217
SQL>   select   low_value, high_value
  2    from     user_tab_columns
  3    where    table_name = 'T'
  4    and      column_name = 'DTE';

LOW_VALUE            HIGH_VALUE
-------------------- -----------------
786F0801010101       786F0807010101
SQL> set serverout on
SQL> declare
  2    res date;
  3 begin
  4    dbms_stats.convert_raw_value(
  5         '786F0801010101',res);
  6    dbms_output.put_line(result);
  7    dbms_stats.convert_raw_value(
  8         '786F0806010101',res);
  9    dbms_output.put_line(result);
 10 end;
 11 /
01-AUG-11
06-AUG-11
01-AUG-11   06-AUG-11
when the time comes…




                       221
as accurate as possible




                          222
as cheaply as possible




                         223
statistics   accurately



                          224
extended statistics




                      225
226
227
cardinality is everything




228
                                  228
same with Oracle




229
                         229
some real(ish) data




230
                            230
SQL> desc VEHICLE

      Name                       Null?      Type
      -------------------------- --------   -------------
      ID                                    NUMBER
      MAKE                                  VARCHAR2(6)
      MODEL                                 VARCHAR2(6)

 SQL> select count(*)
   2 from    VEHICLE;

     COUNT(*)
 ------------
    2,157,079

231
                                                            231
default stats not enough




232
                                 232
SQL> select count(*)
  2 from    VEHICLE
  3 where MAKE = 'HOLDEN';

  COUNT(*)
----------
    415387



------------------------------------------------------------
| Id | Operation          | Name    | Rows | Bytes | Cost |
------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |     7 |   138|
|   1 | SORT AGGREGATE    |         |     1 |     7 |      |
|* 2 |    INDEX RANGE SCAN| MAKE_IX | 55310 |   378K|   138|
------------------------------------------------------------

233
                                                               233
histogram




234
                  234
SQL> begin
        2    dbms_stats.gather_table_stats(user,'VEHICLE',
        3      method_opt=>'for all columns size 1,'||
        4                  'for columns MAKE size 254,'||
        5                  'for columns MODEL size 254');
        6 end;
        7 /

      PL/SQL procedure successfully completed.




235
                                                             235
SQL> select count(*)
  2 from    VEHICLE
  3 where MAKE = 'HOLDEN';

  COUNT(*)
----------
    415387



-----------------------------------------------------------
| Id | Operation          | Name    | Rows | Bytes | Cost |
-----------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |     7 | 1024|
|   1 | SORT AGGREGATE    |         |     1 |     7 |       |
|* 2 |    INDEX RANGE SCAN| MAKE_IX |   418K| 2859K| 1024|
-----------------------------------------------------------


236
                                                                236
make AND model




237
                       237
SQL>    select   count(*)
  2     from     VEHICLE
  3     where    MAKE = 'HOLDEN'
  4     and      MODEL = 'COMMODORE';

  COUNT(*)                              50% holdens are commodores
----------
    214468

--------------------------------------------------------------------
| Id | Operation                         | Name     | Rows | Bytes |
---------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |          |     1 |    14 |
|   1 | SORT AGGREGATE                   |          |     1 |    14 |
|   2 |   BITMAP CONVERSION COUNT        |          | 39527 |   540K|
|   3 |    BITMAP AND                    |          |       |        |
|   4 |     BITMAP CONVERSION FROM ROWIDS|          |       |        |
|* 5 |       INDEX RANGE SCAN            | MODEL_IX |       |        |
|   6 |     BITMAP CONVERSION FROM ROWIDS|          |       |        |
|* 7 |       INDEX RANGE SCAN            | MAKE_IX |        |        |
---------------------------------------------------------------------
  238
                                                                         238
two things




239
                   239
240
241
      241
no correlation



             10g and before

242
                              242
11g




243
            243
SQL> select
   2    DBMS_STATS.CREATE_EXTENDED_STATS(
   3        user, 'VEHICLE','(MAKE,MODEL)') tag
   4 from dual;

 TAG
 ----------------------------------
 SYS_STU8QPK2S$PEWHARK2CP3#1F#G




244
                                                  244
SQL> begin
        2    dbms_stats.gather_table_stats(user,'VEHICLE',
        3      method_opt=>
        4        'for columns (make,model) size 254');
        5 end;
        6 /

      PL/SQL procedure successfully completed.




245
                                                             245
SQL>   select   count(*)
  2    from     VEHICLE
  3    where    MAKE = 'HOLDEN'
  4    and      MODEL = 'COMMODORE';

  COUNT(*)
----------
    214468



-------------------------------------------------------------
| Id | Operation           | Name    | Rows | Bytes | Cost |
------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |    14 | 1956|
|   1 | SORT AGGREGATE     |         |     1 |    14 |      |
|* 2 |    TABLE ACCESS FULL| VEHICLE |   220K| 3018K| 1956|
-------------------------------------------------------------

 246
                                                                246
composite indexes




247
                          247
11.2 column groups




248
                           248
SQL> exec DBMS_STATS.SEED_COL_USAGE(NULL,NULL,60);




 249
                                                     249
implemented via virtual columns




250
                                        250
various implications




251
                             251
accurate stats not always possible...




                                        252
you can't have stats




                       253
on everything !




                  254
when stats wont do...




                        255
... use the real data




                        256
dynamic sampling




                   257
SQL> drop table TOUGH_DATA purge;

Table dropped.

SQL>   create table TOUGH_DATA nologging as
  2    select
  3      rownum pk,
  4      dbms_random.string('U',10) str
  5    from dual
  6    connect by level < 1000000
  7    /

Table created.

SQL> exec dbms_stats.gather_table_stats(
                           user,'TOUGH_DATA')


                                                258
SQL>   select count(*)
  2    from   TOUGH_DATA
  3    where str like '%XX'
  4    /

  COUNT(*)               hard
----------
      1452



                                259
SQL>   select count(*)
  2    from   TOUGH_DATA
  3    where str like '%XX'
  4    /

-------------------------------------------------
| Id | Operation           | Name       | Rows |
-------------------------------------------------
|   0 | SELECT STATEMENT   |            |     1 |
|   1 | SORT AGGREGATE     |            |     1 |
|* 2 |    TABLE ACCESS FULL| TOUGH_DATA | 50000 |
-------------------------------------------------


                              5% assumption
                                                    260
SQL>   select /*+ dynamic_sampling(t 2) */ count(*)
  2    from   TOUGH_DATA t
  3    where str like '%XX'
  4    /

-------------------------------------------------
| Id | Operation           | Name       | Rows |
-------------------------------------------------
|   0 | SELECT STATEMENT   |            |     1 |
|   1 | SORT AGGREGATE     |            |     1 |
|* 2 |    TABLE ACCESS FULL| TOUGH_DATA | 1252 |
-------------------------------------------------




                                                      261
simple queries as well




                         262
1,2,3,4,5,6......                   A,A,A,A,A,B,B,B,B,.....


SQL>   create table EASY_DATA nologging as
  2    select
  3      rownum pk,
  4      chr(65+trunc(rownum/40000)) str
  5    from dual
  6    connect by level < 1000000
  7    /

Table created.

SQL> exec dbms_stats.gather_table_stats(user,'EASY_DATA')

PL/SQL procedure successfully completed.




                                                                263
SQL>   select   count(*)
  2    from     EASY_DATA
  3    where    str = 'F'
  4    and      pk > 900000;

  COUNT(*)
----------
         0




                               264
SQL>   set autotrace traceonly explain
SQL>   select count(*)
  2    from   EASY_DATA
  3    where str = 'F'
  4    and    pk > 900000;

------------------------------------------------
| Id | Operation           | Name      | Rows |
------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |
|   1 | SORT AGGREGATE     |           |     1 |
|* 2 |    TABLE ACCESS FULL| EASY_DATA | 4000 |
------------------------------------------------


                                                   265
SQL>   set autotrace traceonly explain
SQL>   select /*+ dynamic_sampling(t 2) */ count(*)
  2    from   EASY_DATA t
  3    where str = 'F'
  4    and    pk > 900000;

------------------------------------------------
| Id | Operation           | Name      | Rows |
------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |
|   1 | SORT AGGREGATE     |           |     1 |
|* 2 |    TABLE ACCESS FULL| EASY_DATA |    23 |
------------------------------------------------


                                                      266
11.2




       267
parallel queries (maybe) sampled




                                   268
SQL>   select   count(*)
  2    from     EASY_DATA t
  3    where    str = 'F'
  4    and      pk > 900000;

----------------------------------------------------
| Id | Operation               | Name      | Rows |
----------------------------------------------------
|   0 | SELECT STATEMENT       |           |     1 |
|   1 | SORT AGGREGATE         |           |     1 |
|   2 |   PX COORDINATOR       |           |       |
|   3 |    PX SEND QC (RANDOM) | :TQ10000 |      1 |
|   4 |     SORT AGGREGATE     |           |     1 |
|   5 |      PX BLOCK ITERATOR |           |     4 |
|* 6 |        TABLE ACCESS FULL| EASY_DATA |     4 |
----------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=4)
                                                          269
low frequency




                270
high cost




            271
statistics   cheaply



                       272
SQL> desc DBA_TABLES

Name                            Null?      Type
-----------------------------   --------   -------------
OWNER                           NOT NULL   VARCHAR2(30)
TABLE_NAME                      NOT NULL   VARCHAR2(30)
COLUMN_NAME                     NOT NULL   VARCHAR2(30)
...
NUM_ROWS                                   NUMBER




                                                           273
SQL> desc DBA_TAB_COLS

Name                            Null?      Type
-----------------------------   --------   -------------
OWNER                           NOT NULL   VARCHAR2(30)
TABLE_NAME                      NOT NULL   VARCHAR2(30)
COLUMN_NAME                     NOT NULL   VARCHAR2(30)
...
NUM_DISTINCT                               NUMBER
LOW_VALUE                                  RAW(32)
HIGH_VALUE                                 RAW(32)
...




                                                           274
SQL> desc PEOPLE

Name                          Null?      Type
----------------------------- --------   -------------
PID                                      NUMBER
GENDER                                   CHAR(1)
NAME                                     VARCHAR2(47)
AGE                                      NUMBER
DEATH_RATE                               NUMBER




                                                         275
SQL> alter session set sql_true = true;

Session altered.

SQL> begin
  2    dbms_stats.gather_table_stats(
  3      'DEMO',
  4      'PEOPLE);
  5 end;
  6 /



                                          276
select
  /*+ no_parallel(t)
      no_parallel_index(t)
      dbms_stats
      cursor_sharing_exact
      use_weak_name_resl
      dynamic_sampling(0)
      no_monitoring
      no_substrb_pad */
  count(*),
  ...
  count("GENDER")
  count("GENDER"),
                  "GENDER")
  count(distinct "GENDER"),
               min("GENDER")
  substrb(dump(min("GENDER"),16,0,32),1,120),
  substrb(dump(max("GENDER"),16,0,32),1,120),
               max("GENDER")
  ...
from "MCDONAC"."PEOPLE" t

                                                277
count("GENDER")            one pass

count(distinct "GENDER")    hard

min("GENDER")              one pass

max("GENDER")              one pass

                                      278
SQL> select count(*) from PEOPLE;

    COUNT(*)
------------
   500000000

Elapsed: 00:04:43.73




                                    279
SQL> begin
  2    dbms_stats.gather_table_stats(
  3      user,
  4      'PEOPLE',
  5      estimate_percent=>25);
  6 end;
  7 /

ERROR at line 1:
ORA-01652: unable to extend temp
segment by 128 in tablespace TEMP

Elapsed: 00:16:37.12


                                        280
11g




      281
one pass NDV




               282
HASH



12   6   3   12   3   7   11 12 33   6   11 12   6   45 15   7   15 17 45   6   17


12   6   3            7   11    33                   45 15          17
                                                                                     283
12   6   3   7   11   33   45 15   17




                 NDV = 9




                                        284
91

                                 11             34

     12                 7                                      15


          6                                          64
                                           33                        56
                   92



              what about large NDV ?
 21
                                 5                                  61
                                                          45
                        3
              2

                                                                    17
                                      71
73                          41


                                                                          285
"Magic" HASH




               286
NDV =
remaining hashes x
2^number of splits




                     287
demo




       288
SQL> create table ONE_PASS nologging
  2 as select substr(text,1,1) single_char
  3 from DBA_SOURCE;

Table created.

SQL> select count(distinct single_char) ndv
  2 from one_pass;

       NDV
----------
        83


                                              289
0                   127

    16 buckets...


                          290
64   127




           291
96   127




           292
SQL> set serverout on
SQL> declare
  2    type t_bucket is table of varchar2(1);
  3    l_synopsis           t_bucket;
  4    l_splits             number := 0;
  5    l_hash               int;
  6    l_min_val            int := 0;
  7    l_synopsis_size      int := 16;
  8 begin
  9    for i in ( select single_char from one_pass ) loop
 10      l_hash := ascii(i.single_char);
 11
 12      if l_synopsis.count = l_synopsis_size then
 13          l_min_val :=
 14            case
 15              when l_min_val = 0 then 64
 16              when l_min_val = 64 then 96
 17              when l_min_val = 96 then 112
 18              when l_min_val = 112 then 120
 19            end;
 20          l_splits := l_splits + 1;
                                                            293
22
 23         for j in 1 .. l_min_val loop
 24            if l_synopsis.exists(j) then
 25                l_synopsis.delete(j);
 26            end if;
 27         end loop;
 28      end if;
 29
 30      if l_hash > l_min_val then
 31        l_synopsis(l_hash) := 'Y';
 32      end if;
 33    end loop;
 34    dbms_output.put_line(l_synopsis.count *
 35                 power(2,l_splits));
 36 end;
 37 /
Splitting, keeping entries above 64
Splitting, keeping entries above 96
Splitting, keeping entries above 112
88


                                                 294
18,446,744,073,709,551,616 hash range



            the reality


        16384 bucket limit

                                        295
SQL> begin
  2    dbms_stats.gather_table_stats(
  3      user,
  4      'PEOPLE',
  5      estimate_percent=>25);
  6 end;
  7 /

PL/SQL procedure successfully completed.

Elapsed: 00:05:39.82




                                           296
recommendation #4




                    297
estimate_percent

use DEFAULT size (AUTO)




                          298
only for columns

without histograms




                     299
4

Inflammatory
 statements 3
  which will
 alienate the
  audience
           2



           1




                Presentation Duration



                                        300
histograms...




                301
...SUCK
          302
not really but...




                    303
9i




     304
SQL> set autotrace traceonly explain

SQL> select * from MY_TABLE_100K_ROWS
  2 where r = :b1
  3 /

------------------------------------------
| Id | Operation          | Name | Rows |
------------------------------------------
|   0 | SELECT STATEMENT |       |     1 |
|   1 | INDEX UNIQUE SCAN| PK    |     1 |
------------------------------------------



                            ~ num rows / num distinct
                                                    306
SQL> set autotrace traceonly explain

SQL> select * from MY_TABLE_100K_ROWS
  2 where r < :b1
  3 /

-----------------------------------------
| Id | Operation         | Name | Rows |
-----------------------------------------
|   0 | SELECT STATEMENT |      | 5000 |
|   1 | INDEX RANGE SCAN| PK    | 5000 |
-----------------------------------------


                                            5%
                                                 307
308
cool ?




         309
10g




      310
method_opt

for all columns size auto



                            311
sys.col_usage$




                 312
SQL> desc SYS.COL_USAGE$

Name                    Null?      Type
----------------------- --------   ---------
OBJ#                               NUMBER
INTCOL#                            NUMBER
EQUALITY_PREDS                     NUMBER
EQUIJOIN_PREDS                     NUMBER
NONEQUIJOIN_PREDS                  NUMBER
RANGE_PREDS                        NUMBER
LIKE_PREDS                         NUMBER
NULL_PREDS                         NUMBER
TIMESTAMP                          DATE




                                               313
SQL> create table T (                   5 special
  2    skew varchar2(10),
  3    even number);                     values
Table created.

SQL>   insert into T
  2    select
  3      case
  4        when rownum > 99995 then 'SPECIAL'
  5        else dbms_random.string('U',8)
  6      end,
  7      mod(rownum,200)
  8    from dual
  9    connect by level <= 100000          even
 10    /
                                    distribution
100000 rows created.

                                                    314
SQL> exec dbms_stats.gather_table_stats(
            user,'T', estimate_percent=>null);

PL/SQL procedure successfully completed.

SQL>   select COLUMN_NAME,NUM_DISTINCT,DENSITY,
  2           ( select count(*)
  3             from   user_tab_histograms
  4             where table_name = 'T'
  5             and    column_name = c.column_name ) hist_cnt
  6    from user_tab_cols c
  7    where      table_name = 'T'
  8    order by table_name,COLUMN_ID
  9    /

COLUMN_NAME         NUM_DISTINCT    DENSITY   HIST_CNT
------------------- ------------ ---------- ----------
SKEW                       99996     .00001          2
EVEN                         200       .005          2

                                                                315
SQL> select * from T where skew = 'SPECIAL';

SKEW              VAL
---------- ----------
SPECIAL           196
SPECIAL           197
SPECIAL           198
SPECIAL           199
SPECIAL             0

5 rows selected.

SQL> select * from T where even = 5;

TAG               VAL
---------- ----------
IBRXGVIE            5
[snip]

500 rows selected.
                                               316
SQL> exec dbms_stats.gather_table_stats(
            user,'T', estimate_percent=>null);

PL/SQL procedure successfully completed.

SQL>   select COLUMN_NAME,NUM_DISTINCT,DENSITY,
  2           ( select count(*)
  3             from   user_tab_histograms
  4             where table_name = 'T'
  5             and    column_name = c.column_name ) hist_cnt
  6    from user_tab_cols c
  7    where      table_name = 'T'
  8    order by table_name,COLUMN_ID
  9    /

COLUMN_NAME         NUM_DISTINCT    DENSITY   HIST_CNT
------------------- ------------ ---------- ----------
SKEW                       99996     .00001          2
EVEN                         200    .000005        200

                                                                317
recommendation #5




                    318
set_schema_prefs

for all columns size 1




                         319
explicit control for each table




                                  320
set_table_prefs

for column CCC size nnn




                          321
one more useful tool




                       322
323
SQL> desc CONFERENCE_ATTENDEES

 Name                          Null?      Type
 ----------------------------- --------   --------------
 PID                                      NUMBER
 GENDER                                   CHAR(1)
 NAME                                     VARCHAR2(40)
 AGE                                      NUMBER
 DEATH_RATE                               NUMBER




                                                           324
325
SQL> select
  2     count(distinct GENDER) NDV
  3 from
  4     CONFERENCE_ATTENDEES

                   NDV
----------------------
                   ???



                                     326
SQL> select
  2     ntile(GENDER) over ( ... )
  3 from
  4     CONFERENCE_ATTENDEES




                                     327
num_rows


set_table_stats


 avg_row_len

                  328
high_value


set_column_stats


 num_distinct

                   329
when all else fails ...




                          330
... lie and cheat




                    331
332
no




     333
analyze ... validate structure




                                 334
SQL> desc INDEX_STATS

 Name                          Null?      Type
 ----------------------------- --------   --------------
 HEIGHT                                   NUMBER
 BLOCKS                                   NUMBER
 NAME                                     VARCHAR2(30)
 PARTITION_NAME                           VARCHAR2(30)

 ...

 OPT_CMPR_COUNT                           NUMBER
 OPT_CMPR_PCTSAVE                         NUMBER




                                                           335
wrap up




          336
don't collect stats .... unless

don't collect system stats ... unless

don't collect histograms ... unless

    default estimate size (NDV)

           lie and cheat
                                        337
Connor McDonald
    OracleDBA



                co.uk




                        338
ORA-00041
“active time limit exceeded - session terminated”



              www.oracledba.co.uk                   339
11.2




340
             340
actual versus estimate




341
                               341
SQL>   select   /*+ GATHER_PLAN_STATISTICS */ count(*)
  2    from     VEHICLE
  3    where    MAKE = 'HOLDEN'
  4    and      MODEL = 'COMMODORE';

  COUNT(*)
----------
    214468

SQL> SELECT *
  2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(
  3              NULL, NULL, 'ALLSTATS LAST'));

----------------------------------------------------------------
| Id | Operation           | Name    | Starts | E-Rows | A-Rows |
----------------------------------------------------------------
|   1 | SORT AGGREGATE     |         |      1 |      1 |      1 |
|* 2 |    TABLE ACCESS FULL| VEHICLE |      1 |    220K|    214K|
-----------------------------------------------------------------
 342
                                                                342
employ someone....




343
                           343
check every query...




344
                             344
SQL>   select   /*+ GATHER_PLAN_STATISTICS */ count(*)
  2    from     VEHICLE
  3    where    MAKE = 'HOLDEN'
  4    and      MODEL = 'COMMODORE';

  COUNT(*)
----------
    214468

SQL> SELECT *
  2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(
  3              NULL, NULL, 'ALLSTATS LAST'));
                                                         "ok"
-----------------------------------------------------------------
| Id | Operation           | Name    | Starts | E-Rows | A-Rows |
-----------------------------------------------------------------
|   1 | SORT AGGREGATE     |         |      1 |      1 |      1 |
|* 2 |    TABLE ACCESS FULL| VEHICLE |      1 |    220K|    214K|
-----------------------------------------------------------------
 345
                                                                345
346
      346
but just maybe ....




347
                            347
... someone already is




348
                               348
very


       very

          cool
                 349
100,000 rows
SQL>   create table EMP as
  2    select rownum empno,
  3        mod(rownum,10) jobid,
  4        mod(rownum,10)*1000 salary,
  5        mod(rownum,50)+1 deptno
  6    from dual
  7    connect by rownum < 100000;
                                         100 rows
SQL>   create table DEPT as
  2    select rownum deptno,
  3          'dept'||rownum dname
  4    from dual
  5    connect by rownum <= 100;


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

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



SQL> create index EMP_IX on EMP ( deptno );

SQL> create index DEPT_IX on DEPT ( deptno );




                                                        351
SQL>   select e.empno, d.dname                     hard to
  2    from emp e, dept d
  3    where d.deptno = e.deptno                   optimize
  4    and e.jobid = 1
  5    and e.salary > 5000;
    4 and e.jobid = 1
no rows selected

    5 and e.salary > 5000;
----------------------------------------------------------------
| Id | Operation                     | Name    | Rows | Bytes |
----------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |       |       |
|   1 | MERGE JOIN                   |         | 4444 | 104K |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |   100 | 1000 |
|   3 |    INDEX FULL SCAN           | DEPT_IX |   100 |       |
|* 4 |    SORT JOIN                  |         | 4444 | 62216 |
|* 5 |     TABLE ACCESS FULL         | EMP     | 4444 | 62216 |
----------------------------------------------------------------


                                                                   352
re-run the query




                   353
no changes to anything




                         354
SQL>   select e.empno, d.dname
  2    from emp e, dept d
  3    where d.deptno = e.deptno
  4    and e.jobid = 1
  5    and e.salary > 5000;
no rows selected

---------------------------------------------------
| Id | Operation           | Name | Rows | Bytes |
---------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |
|* 1 | HASH JOIN           |      |    89 | 2136 |
|   2 |   TABLE ACCESS FULL| DEPT |     1 |    10 |
|* 3 |    TABLE ACCESS FULL| EMP | 4444 | 62216 |
---------------------------------------------------


                                                      355
11.2




       356
the optimizer knows what "hard" is




                                     357
cardinality feedback loop




                            358
its not continuous




                     359
several restrictions


     but still very cool


                           360

Weitere ähnliche Inhalte

Was ist angesagt?

MySQL Query tuning 101
MySQL Query tuning 101MySQL Query tuning 101
MySQL Query tuning 101Sveta Smirnova
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviewsJustin Swanhart
 
Preparse Query Rewrite Plugins
Preparse Query Rewrite PluginsPreparse Query Rewrite Plugins
Preparse Query Rewrite PluginsSveta Smirnova
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingSveta Smirnova
 
Introducing new SQL syntax and improving performance with preparse Query Rewr...
Introducing new SQL syntax and improving performance with preparse Query Rewr...Introducing new SQL syntax and improving performance with preparse Query Rewr...
Introducing new SQL syntax and improving performance with preparse Query Rewr...Sveta Smirnova
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL PerformanceSveta Smirnova
 
A New View of Database Views
A New View of Database ViewsA New View of Database Views
A New View of Database ViewsMichael Rosenblum
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingSveta Smirnova
 
Performance Schema for MySQL Troubleshooting
 Performance Schema for MySQL Troubleshooting Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingSveta Smirnova
 
Basic MySQL Troubleshooting for Oracle Database Administrators
Basic MySQL Troubleshooting for Oracle Database AdministratorsBasic MySQL Troubleshooting for Oracle Database Administrators
Basic MySQL Troubleshooting for Oracle Database AdministratorsSveta Smirnova
 
MySQL Document Store
MySQL Document StoreMySQL Document Store
MySQL Document StoreI Goo Lee
 
Introduction to MySQL InnoDB Cluster
Introduction to MySQL InnoDB ClusterIntroduction to MySQL InnoDB Cluster
Introduction to MySQL InnoDB ClusterI Goo Lee
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingSveta Smirnova
 
Maximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestMaximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestPythian
 
Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestConnor McDonald
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL PerformanceSveta Smirnova
 
Debunking myths about_redo_ppt
Debunking myths about_redo_pptDebunking myths about_redo_ppt
Debunking myths about_redo_pptRiyaj Shamsudeen
 

Was ist angesagt? (20)

MySQL Query tuning 101
MySQL Query tuning 101MySQL Query tuning 101
MySQL Query tuning 101
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviews
 
Preparse Query Rewrite Plugins
Preparse Query Rewrite PluginsPreparse Query Rewrite Plugins
Preparse Query Rewrite Plugins
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
Introducing new SQL syntax and improving performance with preparse Query Rewr...
Introducing new SQL syntax and improving performance with preparse Query Rewr...Introducing new SQL syntax and improving performance with preparse Query Rewr...
Introducing new SQL syntax and improving performance with preparse Query Rewr...
 
MySQL SQL Tutorial
MySQL SQL TutorialMySQL SQL Tutorial
MySQL SQL Tutorial
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL Performance
 
A New View of Database Views
A New View of Database ViewsA New View of Database Views
A New View of Database Views
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
 
Performance Schema for MySQL Troubleshooting
 Performance Schema for MySQL Troubleshooting Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
Basic MySQL Troubleshooting for Oracle Database Administrators
Basic MySQL Troubleshooting for Oracle Database AdministratorsBasic MySQL Troubleshooting for Oracle Database Administrators
Basic MySQL Troubleshooting for Oracle Database Administrators
 
MySQL Document Store
MySQL Document StoreMySQL Document Store
MySQL Document Store
 
Introduction to MySQL InnoDB Cluster
Introduction to MySQL InnoDB ClusterIntroduction to MySQL InnoDB Cluster
Introduction to MySQL InnoDB Cluster
 
Vertica trace
Vertica traceVertica trace
Vertica trace
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshooting
 
Maximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digestMaximizing SQL Reviews and Tuning with pt-query-digest
Maximizing SQL Reviews and Tuning with pt-query-digest
 
Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolest
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL Performance
 
Debunking myths about_redo_ppt
Debunking myths about_redo_pptDebunking myths about_redo_ppt
Debunking myths about_redo_ppt
 

Andere mochten auch

Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...
Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...
Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...InSync2011
 
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...InSync2011
 
MAGICDB : Mango Genetic stocks Identification and Characterisation Data Base
MAGICDB : Mango Genetic stocks Identification and Characterisation Data BaseMAGICDB : Mango Genetic stocks Identification and Characterisation Data Base
MAGICDB : Mango Genetic stocks Identification and Characterisation Data BaseSenthil Natesan
 
DB2 Accounting Reporting
DB2  Accounting ReportingDB2  Accounting Reporting
DB2 Accounting ReportingJohn Campbell
 
Curs integral-neurologie-sem-1-i-ii
Curs integral-neurologie-sem-1-i-iiCurs integral-neurologie-sem-1-i-ii
Curs integral-neurologie-sem-1-i-iiAlexandra Ally
 
Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero
 Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero
Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - faveroWillie Favero
 
Planning and executing a DB2 11 for z/OS Migration by Ian Cook
Planning and executing a DB2 11 for z/OS  Migration  by Ian Cook Planning and executing a DB2 11 for z/OS  Migration  by Ian Cook
Planning and executing a DB2 11 for z/OS Migration by Ian Cook Surekha Parekh
 

Andere mochten auch (9)

Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...
Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...
Databse & Technology 2 _ Francisco Munoz alvarez _ 11g new functionalities fo...
 
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...
Databse & Technology 2 _ Paul Guerin _ The biggest looser database - a boot c...
 
MAGICDB : Mango Genetic stocks Identification and Characterisation Data Base
MAGICDB : Mango Genetic stocks Identification and Characterisation Data BaseMAGICDB : Mango Genetic stocks Identification and Characterisation Data Base
MAGICDB : Mango Genetic stocks Identification and Characterisation Data Base
 
DB2 Accounting Reporting
DB2  Accounting ReportingDB2  Accounting Reporting
DB2 Accounting Reporting
 
Curs integral-neurologie-sem-1-i-ii
Curs integral-neurologie-sem-1-i-iiCurs integral-neurologie-sem-1-i-ii
Curs integral-neurologie-sem-1-i-ii
 
Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero
 Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero
Universal Table Spaces for DB2 10 for z/OS - IOD 2010 Seesion 1929 - favero
 
Db2
Db2Db2
Db2
 
Planning and executing a DB2 11 for z/OS Migration by Ian Cook
Planning and executing a DB2 11 for z/OS  Migration  by Ian Cook Planning and executing a DB2 11 for z/OS  Migration  by Ian Cook
Planning and executing a DB2 11 for z/OS Migration by Ian Cook
 
Slideshare ppt
Slideshare pptSlideshare ppt
Slideshare ppt
 

Ähnlich wie Databse & Technology 2 | Connor McDonald | Managing Optimiser Statistics - A better way.pdf

SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013Connor McDonald
 
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo... Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...Enkitec
 
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스PgDay.Seoul
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersConnor McDonald
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?Andrej Pashchenko
 
Highload Perf Tuning
Highload Perf TuningHighload Perf Tuning
Highload Perf TuningHighLoad2009
 
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?SegFaultConf
 
Using PostgreSQL statistics to optimize performance
Using PostgreSQL statistics to optimize performance Using PostgreSQL statistics to optimize performance
Using PostgreSQL statistics to optimize performance Alexey Ermakov
 
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdf
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdfDatabase & Technology 1 _ Tom Kyte _ SQL Techniques.pdf
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdfInSync2011
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDMydbops
 
OpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersOpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersConnor McDonald
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenNETWAYS
 
Exadata - Smart Scan Testing
Exadata - Smart Scan TestingExadata - Smart Scan Testing
Exadata - Smart Scan TestingMonowar Mukul
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan DirectivesFranck Pachot
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2Alex Zaballa
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2Alex Zaballa
 
My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2Morgan Tocker
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald PartitioningInSync Conference
 

Ähnlich wie Databse & Technology 2 | Connor McDonald | Managing Optimiser Statistics - A better way.pdf (20)

SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013
 
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo... Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
Tuning SQL for Oracle Exadata: The Good, The Bad, and The Ugly Tuning SQL fo...
 
Performance
PerformancePerformance
Performance
 
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer Disasters
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
Highload Perf Tuning
Highload Perf TuningHighload Perf Tuning
Highload Perf Tuning
 
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
Robert Pankowecki - Czy sprzedawcy SQLowych baz nas oszukali?
 
Using PostgreSQL statistics to optimize performance
Using PostgreSQL statistics to optimize performance Using PostgreSQL statistics to optimize performance
Using PostgreSQL statistics to optimize performance
 
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdf
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdfDatabase & Technology 1 _ Tom Kyte _ SQL Techniques.pdf
Database & Technology 1 _ Tom Kyte _ SQL Techniques.pdf
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
 
OpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersOpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developers
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
 
Exadata - Smart Scan Testing
Exadata - Smart Scan TestingExadata - Smart Scan Testing
Exadata - Smart Scan Testing
 
12c SQL Plan Directives
12c SQL Plan Directives12c SQL Plan Directives
12c SQL Plan Directives
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2
 
DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2DBA Commands and Concepts That Every Developer Should Know - Part 2
DBA Commands and Concepts That Every Developer Should Know - Part 2
 
My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald Partitioning
 
Optimizer Statistics
Optimizer StatisticsOptimizer Statistics
Optimizer Statistics
 

Mehr von InSync2011

Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...
Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...
Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...InSync2011
 
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdf
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdfNew & Emerging _ KrisDowney _ Simplifying the Change Process.pdf
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdfInSync2011
 
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdf
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdfOracle Systems _ Kevin McIsaac _The IT landscape has changed.pdf
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdfInSync2011
 
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdf
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdfReporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdf
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdfInSync2011
 
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...InSync2011
 
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...InSync2011
 
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...InSync2011
 
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...InSync2011
 
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...InSync2011
 
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdf
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdfDatabase & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdf
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdfInSync2011
 
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...InSync2011
 
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...InSync2011
 
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...InSync2011
 
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...InSync2011
 
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...InSync2011
 
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...InSync2011
 
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...InSync2011
 
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...InSync2011
 
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...InSync2011
 
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...InSync2011
 

Mehr von InSync2011 (20)

Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...
Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...
Developer & Fusion Middleware 2 _ Scott Robertson _ SOA, Portals and Enterpri...
 
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdf
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdfNew & Emerging _ KrisDowney _ Simplifying the Change Process.pdf
New & Emerging _ KrisDowney _ Simplifying the Change Process.pdf
 
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdf
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdfOracle Systems _ Kevin McIsaac _The IT landscape has changed.pdf
Oracle Systems _ Kevin McIsaac _The IT landscape has changed.pdf
 
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdf
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdfReporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdf
Reporting _ Scott Tunbridge _ Op Mgmt to Perf Excel.pdf
 
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...
Developer and Fusion Middleware 2 _ Scott Robertson _ SOA, portals and entepr...
 
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...
Primavera _ Loretta Bayliss _ Implementing EPPM in rapidly changing and compe...
 
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...
Database & Technology 1 _ Martin Power _ Delivering Oracles hight availabilit...
 
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...
Database & Technology 1 _ Craig Shallahamer _ Unit of work time based perform...
 
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...
Database & Technology 1 _ Marcelle Kratchvil _ Why you should be storing unst...
 
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdf
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdfDatabase & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdf
Database & Technology 1 _ Milina Ristic _ Why use oracle data guard.pdf
 
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...
Database & Technology 1 _ Clancy Bufton _ Flashback Query - oracle total reca...
 
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...
Databse & Technology 2 _ Francisco Munoz Alvarez _ Oracle Security Tips - Som...
 
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...
Databse & Technology 2 _ Shan Nawaz _ Oracle 11g Top 10 features - not your u...
 
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...
Developer and Fusion Middleware 1 _ Kevin Powe _ Log files - a wealth of fore...
 
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...
Developer and Fusion Middleware 2 _ Aaron Blishen _ Event driven SOA Integrat...
 
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...
Developer and Fusion Middleware 2 _Greg Kirkendall _ How Australia Post teach...
 
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...
Developer and Fusion Middleware 1 _ Paul Ricketts _ Paper Process Automation ...
 
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...
Developer and Fusion Middleware 1 | Mark Nelson | Continuous Integration for ...
 
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...
Developer and Fusion Middleware 2 _Alex Peattie _ An introduction to Oracle S...
 
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...
Developer and Fusion Middleware 1 _ Christian Ledwidge _ Application Performa...
 

Databse & Technology 2 | Connor McDonald | Managing Optimiser Statistics - A better way.pdf

  • 1. NOTE itty bitty fonts in this presentation SQL> exec sample_font Can you read this ? 1
  • 2. Connor McDonald OracleDBA co.uk 2
  • 3. 3
  • 7. 7
  • 8. 8
  • 9. 9
  • 10. why ? 10
  • 11.
  • 12. 12
  • 13.
  • 15. 15
  • 17. 17
  • 21. SQL> analyze table SALES estimate statistics; 21
  • 22. 22
  • 26. SQL> analyze table SALES estimate statistics 2 for table 3 for columns size 10 4 for ....; 26
  • 28. oracle 8i 28
  • 31. SQL> analyze table SALES estimate statistics; 41 characters 31
  • 32. SQL> begin 2 dbms_stats.gather_table_stats( 3 ownname=>'HR', 4 tabname=>'SALES', 5 cascade=>true, 6 estimate_percent=>20 7 ); 8 end; 128 characters 32
  • 34. s l o w e r 34
  • 35. "I don't think so....." 35
  • 37. SQL> desc DBMS_STATS PROCEDURE ALTER_DATABASE_TAB_MONITORING PROCEDURE ALTER_SCHEMA_TAB_MONITORING PROCEDURE ALTER_STATS_HISTORY_RETENTION PROCEDURE CLEANUP_STATS_JOB_PROC PROCEDURE CONVERT_RAW_VALUE PROCEDURE CONVERT_RAW_VALUE PROCEDURE CONVERT_RAW_VALUE PROCEDURE CONVERT_RAW_VALUE PROCEDURE CONVERT_RAW_VALUE PROCEDURE CONVERT_RAW_VALUE_NVARCHAR PROCEDURE CONVERT_RAW_VALUE_ROWID PROCEDURE COPY_TABLE_STATS FUNCTION CREATE_EXTENDED_STATS RETURNS VARCHAR PROCEDURE CREATE_STAT_TABLE PROCEDURE DELETE_COLUMN_STATS 37
  • 39. 39
  • 40. profiles tuning sets baselines features bind peeking adaptive cursor sharing 40
  • 42. ... for the optimizer 42
  • 44. 44
  • 46. ego 46
  • 48. 48
  • 49. 49
  • 50. today.... 50
  • 53. nested loop outer sort merge outer SQL> select count(e.hiredate) 2 from DEPT d, EMP e 3 where e.deptno = d.deptno(+) 4 and e.sal > 10; hash hash anti nested loop anti 53
  • 54. ------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | |* 2 | TABLE ACCESS FULL| EMP | 14 | ------------------------------------------- no DEPT ? 54
  • 55. not null SQL> select count(e.hiredate) 2 from DEPT d, EMP e 3 where e.deptno = d.deptno(+) 4 and e.sal > 10; foreign key 55 key preserved
  • 58. 10g 58
  • 59. SQL> select owner, job_name, enabled 2 from dba_scheduler_jobs 3 where owner = 'SYS'; OWNER JOB_NAME ENABLED --------------- ------------------------------ ------- SYS PURGE_LOG TRUE SYS FGR$AUTOPURGE_JOB TRUE SYS GATHER_STATS_JOB FALSE TRUE SYS AUTO_SPACE_ADVISOR_JOB TRUE 59
  • 60. 11g 60
  • 61. SQL> select owner, job_name, enabled 2 from dba_scheduler_jobs 3 where owner = 'SYS'; OWNER JOB_NAME ENABLED --------------- ------------------------------ ------- SYS AUTO_SPACE_ADVISOR_JOB FALSE SYS BSLN_MAINTAIN_STATS_JOB TRUE SYS DRA_REEVALUATE_OPEN_FAILURES TRUE SYS FGR$AUTOPURGE_JOB FALSE SYS GATHER_STATS_JOB FALSE SYS HM_CREATE_OFFLINE_DICTIONARY FALSE SYS ORA$AUTOTASK_CLEAN TRUE SYS PURGE_LOG TRUE SYS XMLDB_NFS_CLEANUP_JOB FALSE 61
  • 62. stats STILL being collected 62
  • 63. automatic "tasks" "super stealth mode" 63
  • 64. SQL> select client_name, status 2 from DBA_AUTOTASK_CLIENT; CLIENT_NAME STATUS ------------------------------------ -------- auto optimizer stats collection ENABLED auto space advisor ENABLED sql tuning advisor ENABLED 64
  • 65. stats every night most sites default options 65
  • 68. BAD IDEA 68
  • 70. BAD IDEA 70
  • 71. but.... 71
  • 73. GOOD IDEA 73
  • 75. GOOD IDEA 75
  • 76. 76
  • 77. Inflammatory statements which will alienate the audience 1 Presentation Duration 77
  • 80. "I need to change some reference data in my system" 80
  • 83. ITIL 83
  • 85. service call help desk DONE ! problem record
  • 86. phew.... 86
  • 89. "Every night, I would like to potentially change the performance characteristics of every single SQL statement in the database" 89
  • 93. 1987 performance group bstat/estat tkprof BMC patrol afiedt.buf 93
  • 94. "It is only safe to gather statistics ..." "...when to do so will make no difference" 94
  • 96. 96
  • 97. unless things are bad... do not change statistics 97
  • 98. "surely it can't hurt?" 98
  • 99. 10g 99
  • 104. "no queries ran slower" 104
  • 106. problem # 1 106
  • 107. dbms_stats 107
  • 108. the goal of statistics 108
  • 110. added more expensive SQL ! 110
  • 111. SQL> alter session set sql_true = true; Session altered. SQL> begin 2 dbms_stats.gather_table_stats( 3 'DEMO', 4 'PEOPLE); 5 end; 6 / 111
  • 112. SQL> select 2 count(distinct GENDER), 3 min(GENDER), 4 max(GENDER), 5 count(distinct NAME), 6 min(NAME), 7 max(NAME) ... ... 21 from PEOPLE; 112
  • 113. hard ! 113
  • 114.
  • 115. problem #2 115
  • 117. invalidation 117
  • 118.
  • 120. select * insert into PEOPLE from PEOPLE select * from ... select ... from PEOPLE, DEPT where ... SQL> begin 2 dbms_stats.gather_table_stats( 3 'DEMO', 4 'PEOPLE); 5 end; 6 / declare delete from T v people.name%type; where X in begin ( select PID ... from PEOPLE ) 120
  • 121. 121
  • 122. recap 122
  • 123. gathering statistics really hard core SQL belted CPU with hard parsing everything ran the same 123
  • 124. oracle 9 124
  • 125. SQL> desc DBMS_STATS PROCEDURE GATHER_TABLE_STATS Argument Name Type In/Out Default? ----------------------- -------------- ------ -------- OWNNAME VARCHAR2 IN TABNAME VARCHAR2 IN PARTNAME VARCHAR2 IN DEFAULT ESTIMATE_PERCENT NUMBER IN DEFAULT BLOCK_SAMPLE BOOLEAN IN DEFAULT METHOD_OPT VARCHAR2 IN DEFAULT DEGREE NUMBER IN DEFAULT GRANULARITY VARCHAR2 IN DEFAULT CASCADE BOOLEAN IN DEFAULT STATTAB VARCHAR2 IN DEFAULT STATID VARCHAR2 IN DEFAULT STATOWN VARCHAR2 IN DEFAULT NO_INVALIDATE BOOLEAN IN DEFAULT STATTYPE VARCHAR2 IN DEFAULT FORCE BOOLEAN IN DEFAULT 125
  • 126. ? no_invalidate => false | true ? 126
  • 127. oracle 10 127
  • 129. SQL> select 2 x.ksppinm name, 3 y.kspftctxvl value 4 from 5 sys.x$ksppi x, 6 sys.x$ksppcv2 y 7 where 8 x.indx+1 = y.kspftctxpn and 9 x.ksppinm = '_optimizer_invalidation_period' NAME VALUE ------------------------------ ------------ _optimizer_invalidation_period 18000 129
  • 130. select * insert into PEOPLE from PEOPLE select * from ... select ... from PEOPLE, DEPT where ... SQL> exec dbms_stats.gather_table_stats( user,'PEOPLE'); declare delete from T v people.name%type; where X in begin ( select PID ... from PEOPLE ) 130
  • 131. better ? 131
  • 132. hard parse storm avoided 132
  • 133. 5 hours before problems 133
  • 134. 134
  • 135. unless things are bad... DO NOT CHANGE STATISTICS 135
  • 136. Inflammatory statements which will alienate the audience 2 1 Presentation Duration 136
  • 137. we don't know if things are bad 137
  • 138. until its too late 138
  • 139. users fed up SQL's are slow stats out of date 139
  • 140. 140
  • 141. 141
  • 142. 2 hours to gather stats 142
  • 143. 143
  • 145. in readiness 145
  • 146. 146
  • 148. "published" – optimizer uses "pending" - private 148
  • 149. SQL> begin 2 dbms_stats.set_schema_prefs( 3 ownname=>'DEMO', 4 pname=>'PUBLISH', 5 pvalue=>'FALSE'); 6 end; database, table 149
  • 150. SQL> alter session set 2 optimizer_use_pending_statistics = true; 150
  • 151. SQL> begin 2 dbms_stats.publish_pending_stats( 3 ownname=>'DEMO', 4 tabname=>null); 5 end; 151
  • 154. PUBLISH = false always.... 154
  • 155. even if you immediately publish 155
  • 157. and don't wait 5 hours 157
  • 163. absolutely vital… …to have them 163
  • 165. SQL> set autotrace traceonly explain SQL> select * from T; --------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 53459 | 4489K| 113 (1)| | 1 | TABLE ACCESS FULL| T | 53459 | 4489K| 113 (1)| --------------------------------------------------------------- SQL> select value 2 from v$spparameter 3 where name = 'db_file_multiblock_read_count'; VALUE ----------- 16 165
  • 166. SQL> alter session set events 2 = '10046 trace name context forever, level 8'; SQL> select * from T; PARSING IN CURSOR #22 len=15 dep=0 uid=124 oct=3 lid=124 ... select * from T END OF STMT PARSE #22:c=10000,e=108,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4 EXEC #22:c=0,e=65,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4 WAIT #22: nam='db file scattered read' ela= 3387 file#=5 block#=13122 blocks=16 obj#=199963 WAIT #22: nam='db file scattered read' ela= 3188 file#=5 block#=13234 blocks=16 obj#=199963 WAIT #22: nam='db file scattered read' ela= 3125 file#=5 block#=13250 blocks=16 obj#=199963 WAIT #22: nam='db file scattered read' ela= 3255 file#=5 block#=13266 blocks=16 obj#=199963 WAIT #22: nam='db file scattered read' ela= 3369 file#=5 block#=13282 blocks=16 obj#=199963 166
  • 171. ? 171
  • 172. 172
  • 175. SQL> select pname, pval1 2 from sys.aux_stats$ 3 / PNAME PVAL1 ------------------------------ ---------- SREADTIM 4.065 MREADTIM 6.173 CPUSPEED 567 MBRC 12 MAXTHR 48203776 SLAVETHR -1 175
  • 176. use MBRC to cost 176
  • 178. Inflammatory statements 3 which will alienate the audience 2 1 Presentation Duration 178
  • 179. forget about system statistics 179
  • 180. do not use them 180
  • 181. 181
  • 182. 182
  • 183. absolutely vital… …to have them 183
  • 184. do not “use”* them * = collect, change, set 184
  • 185. problem #1 185
  • 186. 186
  • 187. problem #2 187
  • 191. gather into STAT table 191
  • 192. monitor 192
  • 193. set once 193
  • 194. the defaults are probably fine 194
  • 195. SQL> select pname, pval1 2 from sys.aux_stats$ 3 / PNAME PVAL1 ---------------------- ---------- IOSEEKTIM 10 (ms) IOTFRSPEED 4096 (bytes/ms) SREADTIM = IOSEEKTIM + db_block_size / IOTFRSPEED = 10 MREADTIM = IOSEEKTIM + mbrc * db_block_size / IOTFRSPEED = 26 195
  • 198. dbms_resource_manager to calibrate 198
  • 199. so far... 199
  • 202. the time will come... 202
  • 204. even if stats unchanged … 204
  • 205. … your plans might ! 205
  • 206. SQL> create table T as 2 select to_date('01-AUG-2011')+ 3 trunc(dbms_random.value(0,7)) dte, 4 rpad('padding',20) padding 5 from dual 6 connect by level <= 100000; Table created.
  • 207. SQL> select dte, count(*) 2 from t 3 group by dte 4 order by 1; DTE COUNT(*) --------- ---------- 01-AUG-11 14334 02-AUG-11 14222 03-AUG-11 14167 04-AUG-11 14510 05-AUG-11 14346 06-AUG-11 14349 07-AUG-11 14072
  • 208. 15,000 rows per day always 208
  • 209. SQL> exec dbms_stats.gather_table_stats(user,'T') PL/SQL procedure successfully completed. SQL> create index IX on T ( dte ) ; Index created.
  • 210. SQL> select * from t where dte = '03-AUG-2011'; -------------------------------------------------- | Id | Operation | Name | Rows | Bytes | -------------------------------------------------- | 0 | SELECT STATEMENT | | 14286 | 404K| |* 1 | TABLE ACCESS FULL| T | 14286 | 404K| --------------------------------------------------
  • 212. SQL> insert into T 2 select to_date('08-AUG-2011')+ 3 trunc(dbms_random.value(0,7)) dte, 4 rpad('padding',20) padding 5 from dual 6 connect by level <= 100000; 100000 rows created.
  • 213. SQL> select dte, count(*) 2 from t 3 group by dte 4 order by 1; DTE COUNT(*) --------- ---------- 01-AUG-11 14334 ... 07-AUG-11 14072 08-AUG-11 14261 09-AUG-11 14106 10-AUG-11 14410 11-AUG-11 14289 12-AUG-11 14358 13-AUG-11 14252 14-AUG-11 14324
  • 215. SQL> select * from t where dte = '12-AUG-2011'; ---------------------------------------------------- | Id | Operation | Name | Rows | ---------------------------------------------------- | 0 | SELECT STATEMENT | | 2381 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 2381 | |* 2 | INDEX RANGE SCAN | IX | 2381 | ----------------------------------------------------
  • 216. SQL> select * from t where dte = '14-AUG-2011'; ---------------------------------------------------- | Id | Operation | Name | Rows | ---------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | |* 2 | INDEX RANGE SCAN | IX | 1 | ----------------------------------------------------
  • 217. why ? 217
  • 218. SQL> select low_value, high_value 2 from user_tab_columns 3 where table_name = 'T' 4 and column_name = 'DTE'; LOW_VALUE HIGH_VALUE -------------------- ----------------- 786F0801010101 786F0807010101
  • 219. SQL> set serverout on SQL> declare 2 res date; 3 begin 4 dbms_stats.convert_raw_value( 5 '786F0801010101',res); 6 dbms_output.put_line(result); 7 dbms_stats.convert_raw_value( 8 '786F0806010101',res); 9 dbms_output.put_line(result); 10 end; 11 / 01-AUG-11 06-AUG-11
  • 220. 01-AUG-11 06-AUG-11
  • 221. when the time comes… 221
  • 222. as accurate as possible 222
  • 223. as cheaply as possible 223
  • 224. statistics accurately 224
  • 226. 226
  • 227. 227
  • 231. SQL> desc VEHICLE Name Null? Type -------------------------- -------- ------------- ID NUMBER MAKE VARCHAR2(6) MODEL VARCHAR2(6) SQL> select count(*) 2 from VEHICLE; COUNT(*) ------------ 2,157,079 231 231
  • 232. default stats not enough 232 232
  • 233. SQL> select count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN'; COUNT(*) ---------- 415387 ------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 7 | 138| | 1 | SORT AGGREGATE | | 1 | 7 | | |* 2 | INDEX RANGE SCAN| MAKE_IX | 55310 | 378K| 138| ------------------------------------------------------------ 233 233
  • 235. SQL> begin 2 dbms_stats.gather_table_stats(user,'VEHICLE', 3 method_opt=>'for all columns size 1,'|| 4 'for columns MAKE size 254,'|| 5 'for columns MODEL size 254'); 6 end; 7 / PL/SQL procedure successfully completed. 235 235
  • 236. SQL> select count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN'; COUNT(*) ---------- 415387 ----------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ----------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 7 | 1024| | 1 | SORT AGGREGATE | | 1 | 7 | | |* 2 | INDEX RANGE SCAN| MAKE_IX | 418K| 2859K| 1024| ----------------------------------------------------------- 236 236
  • 238. SQL> select count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN' 4 and MODEL = 'COMMODORE'; COUNT(*) 50% holdens are commodores ---------- 214468 -------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | --------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | | 1 | SORT AGGREGATE | | 1 | 14 | | 2 | BITMAP CONVERSION COUNT | | 39527 | 540K| | 3 | BITMAP AND | | | | | 4 | BITMAP CONVERSION FROM ROWIDS| | | | |* 5 | INDEX RANGE SCAN | MODEL_IX | | | | 6 | BITMAP CONVERSION FROM ROWIDS| | | | |* 7 | INDEX RANGE SCAN | MAKE_IX | | | --------------------------------------------------------------------- 238 238
  • 240. 240
  • 241. 241 241
  • 242. no correlation 10g and before 242 242
  • 243. 11g 243 243
  • 244. SQL> select 2 DBMS_STATS.CREATE_EXTENDED_STATS( 3 user, 'VEHICLE','(MAKE,MODEL)') tag 4 from dual; TAG ---------------------------------- SYS_STU8QPK2S$PEWHARK2CP3#1F#G 244 244
  • 245. SQL> begin 2 dbms_stats.gather_table_stats(user,'VEHICLE', 3 method_opt=> 4 'for columns (make,model) size 254'); 5 end; 6 / PL/SQL procedure successfully completed. 245 245
  • 246. SQL> select count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN' 4 and MODEL = 'COMMODORE'; COUNT(*) ---------- 214468 ------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 14 | 1956| | 1 | SORT AGGREGATE | | 1 | 14 | | |* 2 | TABLE ACCESS FULL| VEHICLE | 220K| 3018K| 1956| ------------------------------------------------------------- 246 246
  • 250. implemented via virtual columns 250 250
  • 252. accurate stats not always possible... 252
  • 253. you can't have stats 253
  • 255. when stats wont do... 255
  • 256. ... use the real data 256
  • 258. SQL> drop table TOUGH_DATA purge; Table dropped. SQL> create table TOUGH_DATA nologging as 2 select 3 rownum pk, 4 dbms_random.string('U',10) str 5 from dual 6 connect by level < 1000000 7 / Table created. SQL> exec dbms_stats.gather_table_stats( user,'TOUGH_DATA') 258
  • 259. SQL> select count(*) 2 from TOUGH_DATA 3 where str like '%XX' 4 / COUNT(*) hard ---------- 1452 259
  • 260. SQL> select count(*) 2 from TOUGH_DATA 3 where str like '%XX' 4 / ------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | |* 2 | TABLE ACCESS FULL| TOUGH_DATA | 50000 | ------------------------------------------------- 5% assumption 260
  • 261. SQL> select /*+ dynamic_sampling(t 2) */ count(*) 2 from TOUGH_DATA t 3 where str like '%XX' 4 / ------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | |* 2 | TABLE ACCESS FULL| TOUGH_DATA | 1252 | ------------------------------------------------- 261
  • 262. simple queries as well 262
  • 263. 1,2,3,4,5,6...... A,A,A,A,A,B,B,B,B,..... SQL> create table EASY_DATA nologging as 2 select 3 rownum pk, 4 chr(65+trunc(rownum/40000)) str 5 from dual 6 connect by level < 1000000 7 / Table created. SQL> exec dbms_stats.gather_table_stats(user,'EASY_DATA') PL/SQL procedure successfully completed. 263
  • 264. SQL> select count(*) 2 from EASY_DATA 3 where str = 'F' 4 and pk > 900000; COUNT(*) ---------- 0 264
  • 265. SQL> set autotrace traceonly explain SQL> select count(*) 2 from EASY_DATA 3 where str = 'F' 4 and pk > 900000; ------------------------------------------------ | Id | Operation | Name | Rows | ------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | |* 2 | TABLE ACCESS FULL| EASY_DATA | 4000 | ------------------------------------------------ 265
  • 266. SQL> set autotrace traceonly explain SQL> select /*+ dynamic_sampling(t 2) */ count(*) 2 from EASY_DATA t 3 where str = 'F' 4 and pk > 900000; ------------------------------------------------ | Id | Operation | Name | Rows | ------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | |* 2 | TABLE ACCESS FULL| EASY_DATA | 23 | ------------------------------------------------ 266
  • 267. 11.2 267
  • 268. parallel queries (maybe) sampled 268
  • 269. SQL> select count(*) 2 from EASY_DATA t 3 where str = 'F' 4 and pk > 900000; ---------------------------------------------------- | Id | Operation | Name | Rows | ---------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | SORT AGGREGATE | | 1 | | 2 | PX COORDINATOR | | | | 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | | 4 | SORT AGGREGATE | | 1 | | 5 | PX BLOCK ITERATOR | | 4 | |* 6 | TABLE ACCESS FULL| EASY_DATA | 4 | ---------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=4) 269
  • 271. high cost 271
  • 272. statistics cheaply 272
  • 273. SQL> desc DBA_TABLES Name Null? Type ----------------------------- -------- ------------- OWNER NOT NULL VARCHAR2(30) TABLE_NAME NOT NULL VARCHAR2(30) COLUMN_NAME NOT NULL VARCHAR2(30) ... NUM_ROWS NUMBER 273
  • 274. SQL> desc DBA_TAB_COLS Name Null? Type ----------------------------- -------- ------------- OWNER NOT NULL VARCHAR2(30) TABLE_NAME NOT NULL VARCHAR2(30) COLUMN_NAME NOT NULL VARCHAR2(30) ... NUM_DISTINCT NUMBER LOW_VALUE RAW(32) HIGH_VALUE RAW(32) ... 274
  • 275. SQL> desc PEOPLE Name Null? Type ----------------------------- -------- ------------- PID NUMBER GENDER CHAR(1) NAME VARCHAR2(47) AGE NUMBER DEATH_RATE NUMBER 275
  • 276. SQL> alter session set sql_true = true; Session altered. SQL> begin 2 dbms_stats.gather_table_stats( 3 'DEMO', 4 'PEOPLE); 5 end; 6 / 276
  • 277. select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring no_substrb_pad */ count(*), ... count("GENDER") count("GENDER"), "GENDER") count(distinct "GENDER"), min("GENDER") substrb(dump(min("GENDER"),16,0,32),1,120), substrb(dump(max("GENDER"),16,0,32),1,120), max("GENDER") ... from "MCDONAC"."PEOPLE" t 277
  • 278. count("GENDER") one pass count(distinct "GENDER") hard min("GENDER") one pass max("GENDER") one pass 278
  • 279. SQL> select count(*) from PEOPLE; COUNT(*) ------------ 500000000 Elapsed: 00:04:43.73 279
  • 280. SQL> begin 2 dbms_stats.gather_table_stats( 3 user, 4 'PEOPLE', 5 estimate_percent=>25); 6 end; 7 / ERROR at line 1: ORA-01652: unable to extend temp segment by 128 in tablespace TEMP Elapsed: 00:16:37.12 280
  • 281. 11g 281
  • 282. one pass NDV 282
  • 283. HASH 12 6 3 12 3 7 11 12 33 6 11 12 6 45 15 7 15 17 45 6 17 12 6 3 7 11 33 45 15 17 283
  • 284. 12 6 3 7 11 33 45 15 17 NDV = 9 284
  • 285. 91 11 34 12 7 15 6 64 33 56 92 what about large NDV ? 21 5 61 45 3 2 17 71 73 41 285
  • 286. "Magic" HASH 286
  • 287. NDV = remaining hashes x 2^number of splits 287
  • 288. demo 288
  • 289. SQL> create table ONE_PASS nologging 2 as select substr(text,1,1) single_char 3 from DBA_SOURCE; Table created. SQL> select count(distinct single_char) ndv 2 from one_pass; NDV ---------- 83 289
  • 290. 0 127 16 buckets... 290
  • 291. 64 127 291
  • 292. 96 127 292
  • 293. SQL> set serverout on SQL> declare 2 type t_bucket is table of varchar2(1); 3 l_synopsis t_bucket; 4 l_splits number := 0; 5 l_hash int; 6 l_min_val int := 0; 7 l_synopsis_size int := 16; 8 begin 9 for i in ( select single_char from one_pass ) loop 10 l_hash := ascii(i.single_char); 11 12 if l_synopsis.count = l_synopsis_size then 13 l_min_val := 14 case 15 when l_min_val = 0 then 64 16 when l_min_val = 64 then 96 17 when l_min_val = 96 then 112 18 when l_min_val = 112 then 120 19 end; 20 l_splits := l_splits + 1; 293
  • 294. 22 23 for j in 1 .. l_min_val loop 24 if l_synopsis.exists(j) then 25 l_synopsis.delete(j); 26 end if; 27 end loop; 28 end if; 29 30 if l_hash > l_min_val then 31 l_synopsis(l_hash) := 'Y'; 32 end if; 33 end loop; 34 dbms_output.put_line(l_synopsis.count * 35 power(2,l_splits)); 36 end; 37 / Splitting, keeping entries above 64 Splitting, keeping entries above 96 Splitting, keeping entries above 112 88 294
  • 295. 18,446,744,073,709,551,616 hash range the reality 16384 bucket limit 295
  • 296. SQL> begin 2 dbms_stats.gather_table_stats( 3 user, 4 'PEOPLE', 5 estimate_percent=>25); 6 end; 7 / PL/SQL procedure successfully completed. Elapsed: 00:05:39.82 296
  • 299. only for columns without histograms 299
  • 300. 4 Inflammatory statements 3 which will alienate the audience 2 1 Presentation Duration 300
  • 302. ...SUCK 302
  • 304. 9i 304
  • 305.
  • 306. SQL> set autotrace traceonly explain SQL> select * from MY_TABLE_100K_ROWS 2 where r = :b1 3 / ------------------------------------------ | Id | Operation | Name | Rows | ------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 1 | INDEX UNIQUE SCAN| PK | 1 | ------------------------------------------ ~ num rows / num distinct 306
  • 307. SQL> set autotrace traceonly explain SQL> select * from MY_TABLE_100K_ROWS 2 where r < :b1 3 / ----------------------------------------- | Id | Operation | Name | Rows | ----------------------------------------- | 0 | SELECT STATEMENT | | 5000 | | 1 | INDEX RANGE SCAN| PK | 5000 | ----------------------------------------- 5% 307
  • 308. 308
  • 309. cool ? 309
  • 310. 10g 310
  • 311. method_opt for all columns size auto 311
  • 313. SQL> desc SYS.COL_USAGE$ Name Null? Type ----------------------- -------- --------- OBJ# NUMBER INTCOL# NUMBER EQUALITY_PREDS NUMBER EQUIJOIN_PREDS NUMBER NONEQUIJOIN_PREDS NUMBER RANGE_PREDS NUMBER LIKE_PREDS NUMBER NULL_PREDS NUMBER TIMESTAMP DATE 313
  • 314. SQL> create table T ( 5 special 2 skew varchar2(10), 3 even number); values Table created. SQL> insert into T 2 select 3 case 4 when rownum > 99995 then 'SPECIAL' 5 else dbms_random.string('U',8) 6 end, 7 mod(rownum,200) 8 from dual 9 connect by level <= 100000 even 10 / distribution 100000 rows created. 314
  • 315. SQL> exec dbms_stats.gather_table_stats( user,'T', estimate_percent=>null); PL/SQL procedure successfully completed. SQL> select COLUMN_NAME,NUM_DISTINCT,DENSITY, 2 ( select count(*) 3 from user_tab_histograms 4 where table_name = 'T' 5 and column_name = c.column_name ) hist_cnt 6 from user_tab_cols c 7 where table_name = 'T' 8 order by table_name,COLUMN_ID 9 / COLUMN_NAME NUM_DISTINCT DENSITY HIST_CNT ------------------- ------------ ---------- ---------- SKEW 99996 .00001 2 EVEN 200 .005 2 315
  • 316. SQL> select * from T where skew = 'SPECIAL'; SKEW VAL ---------- ---------- SPECIAL 196 SPECIAL 197 SPECIAL 198 SPECIAL 199 SPECIAL 0 5 rows selected. SQL> select * from T where even = 5; TAG VAL ---------- ---------- IBRXGVIE 5 [snip] 500 rows selected. 316
  • 317. SQL> exec dbms_stats.gather_table_stats( user,'T', estimate_percent=>null); PL/SQL procedure successfully completed. SQL> select COLUMN_NAME,NUM_DISTINCT,DENSITY, 2 ( select count(*) 3 from user_tab_histograms 4 where table_name = 'T' 5 and column_name = c.column_name ) hist_cnt 6 from user_tab_cols c 7 where table_name = 'T' 8 order by table_name,COLUMN_ID 9 / COLUMN_NAME NUM_DISTINCT DENSITY HIST_CNT ------------------- ------------ ---------- ---------- SKEW 99996 .00001 2 EVEN 200 .000005 200 317
  • 320. explicit control for each table 320
  • 322. one more useful tool 322
  • 323. 323
  • 324. SQL> desc CONFERENCE_ATTENDEES Name Null? Type ----------------------------- -------- -------------- PID NUMBER GENDER CHAR(1) NAME VARCHAR2(40) AGE NUMBER DEATH_RATE NUMBER 324
  • 325. 325
  • 326. SQL> select 2 count(distinct GENDER) NDV 3 from 4 CONFERENCE_ATTENDEES NDV ---------------------- ??? 326
  • 327. SQL> select 2 ntile(GENDER) over ( ... ) 3 from 4 CONFERENCE_ATTENDEES 327
  • 330. when all else fails ... 330
  • 331. ... lie and cheat 331
  • 332. 332
  • 333. no 333
  • 334. analyze ... validate structure 334
  • 335. SQL> desc INDEX_STATS Name Null? Type ----------------------------- -------- -------------- HEIGHT NUMBER BLOCKS NUMBER NAME VARCHAR2(30) PARTITION_NAME VARCHAR2(30) ... OPT_CMPR_COUNT NUMBER OPT_CMPR_PCTSAVE NUMBER 335
  • 336. wrap up 336
  • 337. don't collect stats .... unless don't collect system stats ... unless don't collect histograms ... unless default estimate size (NDV) lie and cheat 337
  • 338. Connor McDonald OracleDBA co.uk 338
  • 339. ORA-00041 “active time limit exceeded - session terminated” www.oracledba.co.uk 339
  • 340. 11.2 340 340
  • 342. SQL> select /*+ GATHER_PLAN_STATISTICS */ count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN' 4 and MODEL = 'COMMODORE'; COUNT(*) ---------- 214468 SQL> SELECT * 2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR( 3 NULL, NULL, 'ALLSTATS LAST')); ---------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | ---------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 1 | |* 2 | TABLE ACCESS FULL| VEHICLE | 1 | 220K| 214K| ----------------------------------------------------------------- 342 342
  • 345. SQL> select /*+ GATHER_PLAN_STATISTICS */ count(*) 2 from VEHICLE 3 where MAKE = 'HOLDEN' 4 and MODEL = 'COMMODORE'; COUNT(*) ---------- 214468 SQL> SELECT * 2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR( 3 NULL, NULL, 'ALLSTATS LAST')); "ok" ----------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | ----------------------------------------------------------------- | 1 | SORT AGGREGATE | | 1 | 1 | 1 | |* 2 | TABLE ACCESS FULL| VEHICLE | 1 | 220K| 214K| ----------------------------------------------------------------- 345 345
  • 346. 346 346
  • 347. but just maybe .... 347 347
  • 348. ... someone already is 348 348
  • 349. very very cool 349
  • 350. 100,000 rows SQL> create table EMP as 2 select rownum empno, 3 mod(rownum,10) jobid, 4 mod(rownum,10)*1000 salary, 5 mod(rownum,50)+1 deptno 6 from dual 7 connect by rownum < 100000; 100 rows SQL> create table DEPT as 2 select rownum deptno, 3 'dept'||rownum dname 4 from dual 5 connect by rownum <= 100; 350
  • 351. SQL> exec dbms_stats.gather_table_stats(user,'EMP'); SQL> exec dbms_stats.gather_table_stats(user,'DEPT'); SQL> create index EMP_IX on EMP ( deptno ); SQL> create index DEPT_IX on DEPT ( deptno ); 351
  • 352. SQL> select e.empno, d.dname hard to 2 from emp e, dept d 3 where d.deptno = e.deptno optimize 4 and e.jobid = 1 5 and e.salary > 5000; 4 and e.jobid = 1 no rows selected 5 and e.salary > 5000; ---------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | ---------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | MERGE JOIN | | 4444 | 104K | | 2 | TABLE ACCESS BY INDEX ROWID| DEPT | 100 | 1000 | | 3 | INDEX FULL SCAN | DEPT_IX | 100 | | |* 4 | SORT JOIN | | 4444 | 62216 | |* 5 | TABLE ACCESS FULL | EMP | 4444 | 62216 | ---------------------------------------------------------------- 352
  • 354. no changes to anything 354
  • 355. SQL> select e.empno, d.dname 2 from emp e, dept d 3 where d.deptno = e.deptno 4 and e.jobid = 1 5 and e.salary > 5000; no rows selected --------------------------------------------------- | Id | Operation | Name | Rows | Bytes | --------------------------------------------------- | 0 | SELECT STATEMENT | | | | |* 1 | HASH JOIN | | 89 | 2136 | | 2 | TABLE ACCESS FULL| DEPT | 1 | 10 | |* 3 | TABLE ACCESS FULL| EMP | 4444 | 62216 | --------------------------------------------------- 355
  • 356. 11.2 356
  • 357. the optimizer knows what "hard" is 357
  • 360. several restrictions but still very cool 360