SlideShare une entreprise Scribd logo
1  sur  381
Télécharger pour lire hors ligne
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
6
why ?


        ...now

                 7
version 8.0




              8
9
10
a personal history




                     11
80's




       12
13
14
Walker Interactive




                     15
Jeff Walker...




                 16
20G




      17
$200

per gigabyte

 per month



               19
Storage
    is
expensive




            20
Archive



          21
22
90's




       23
24
JBOD




       25
Storage
   is
 cheap !




           26
Archive



          27
Archive



          28
1992   1996   1999
30
00's




       31
disk is even cheaper....




                           32
33
....but




          34
keep everything !




                    36
JBOD




       37
38
HBA

 Infiniband

    Filer

    Cache

Fibre Channel

     etc
                39
Storage
   is
 cheap !




           40
Storage    Storage
    is         is
expensive    cheap !




                       41
CEO




      42
brings us to today...




                        43
ILM
      44
Information



 Lifecycle


Management

              45
keep everything .... cheaply




                               46
put the new stuff on good storage

   keep everything .... cheaply

put the old stuff on crappy storage


                                    47
split stuff up




                 48
49
basics




         50
range partitioning


            since 8.0

                        51
SALES


2009   2010   2011   2012




                            52
provocative statement




                        53
"all applications are (time)
     windows on data"




               http://thehelsinkideclaration.blogspot.com/

                                                             54
corollary:

everyone can benefit
from range partitions



                        55
time the most common




                       56
SQL> create table DEMO
  2  ( tstamp       timestamp(6) not null,
  3    empno        number(10)   not null,
  4    ename        varchar2(10) not null,
  5    deptno       varchar2(10) not null
  6  )
  7  PARTITION BY RANGE (TSTAMP)
  8  (
  9    PARTITION p01 VALUES LESS THAN
 10        (TIMESTAMP' 2010-01-01 00:00:00'),
 11    PARTITION p02 VALUES LESS THAN
 12        (TIMESTAMP' 2010-02-01 00:00:00'),
 13    PARTITION p03 VALUES LESS THAN
 14        (TIMESTAMP' 2010-03-01 00:00:00'),
     ...
     ...
 25    PARTITION p13 VALUES LESS THAN
 26        (TIMESTAMP' 2011-01-01 00:00:00')
 27 );

Table created.

                                                57
SQL> select partition_name pname,
  2         partition_position pos,
  3         high_value
  4 from    USER_TAB_PARTITIONS
  5 where table_name = 'DEMO';

PNAME        POS HIGH_VALUE
----- ---------- -------------------------------
P01            1 TIMESTAMP' 2010-01-01 00:00:00'
P02            2 TIMESTAMP' 2010-02-01 00:00:00'
P03            3 TIMESTAMP' 2010-03-01 00:00:00'
P04            4 TIMESTAMP' 2010-04-01 00:00:00'
P05            5 TIMESTAMP' 2010-05-01 00:00:00'
P06            6 TIMESTAMP' 2010-06-01 00:00:00'
P07            7 TIMESTAMP' 2010-07-01 00:00:00'
P08            8 TIMESTAMP' 2010-08-01 00:00:00'
P09            9 TIMESTAMP' 2010-09-01 00:00:00'
P10           10 TIMESTAMP' 2010-10-01 00:00:00'
P11           11 TIMESTAMP' 2010-11-01 00:00:00'
P12           12 TIMESTAMP' 2010-12-01 00:00:00'
P13           13 TIMESTAMP' 2011-01-01 00:00:00'
                                                   58
range partition boundaries




                             59
split by upper bound




                       60
P02 >=    2010-01-01
P02 <     2010-02-01

    PARTITION p01 VALUES LESS THAN
        (TIMESTAMP' 2010-01-01 00:00:00'),

    PARTITION p02 VALUES LESS THAN
        (TIMESTAMP' 2010-02-01 00:00:00'),




                       January not February

                                              61
possible benefits




                    62
performance




              63
partition pruning




                    64
SQL> set autotrace traceonly explain

SQL> select * from DEMO
  2 where TSTAMP = to_date('11-JUN-2010');

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     1 |       |       |
|   1 | PARTITION RANGE SINGLE|       |     1 |     7 |     7 |
|* 2 |    TABLE ACCESS FULL    | DEMO |     1 |     7 |     7 |
---------------------------------------------------------------




                                                                  65
SQL> select partition_name pname,
  2         partition_position pos,
  3         high_value
  4 from    user_tab_partitions
  5 where table_name = 'DEMO';

PNAME        POS HIGH_VALUE
----- ---------- -------------------------------
P01            1 TIMESTAMP' 2010-01-01 00:00:00'
P02            2 TIMESTAMP' 2010-02-01 00:00:00'
P03            3 TIMESTAMP' 2010-03-01 00:00:00'
P04            4 TIMESTAMP' 2010-04-01 00:00:00'
P05            5 TIMESTAMP' 2010-05-01 00:00:00'
P06            6 TIMESTAMP' 2010-06-01 00:00:00'
P07            7 TIMESTAMP' 2010-07-01 00:00:00'
P08            8 TIMESTAMP' 2010-08-01 00:00:00'
P09            9 TIMESTAMP' 2010-09-01 00:00:00'
P10           10 TIMESTAMP' 2010-10-01 00:00:00'
P11           11 TIMESTAMP' 2010-11-01 00:00:00'
P12           12 TIMESTAMP' 2010-12-01 00:00:00'
P13           13 TIMESTAMP' 2011-01-01 00:00:00'
                                                   66
more later...




                67
dbms_xplan




             68
SQL> explain plan for select ....

SQL> select *
  2 from table(dbms_xplan.display)




                                     69
SQL> select *
  2 from table(
  3     dbms_xplan.display(
  4       format=>'PARTITION -COST -BYTES'));




                                                70
SQL> select *
  2 from table(dbms_xplan.display_awr(...))




                                              71
SQL> select ...

SQL> select *
  2 from table(dbms_xplan.display_cursor)




                                            72
SQL> select *
  2 from table(dbms_xplan.display_plan_baseline)




                                               73
back to range partitioning




                             74
add / drop

      move

  cache control

maintenance

     rebuild


backup / read-only

     compress
                     75
partition loss


availability

   recovery


                  a little dubious....

                                         76
multi-column range




                     77
SQL>   create table SALES_DATA
  2    ( yyyy            number(4) not null,
  3       mm             number(2) not null,
  4       sales_id       varchar2(10) not null,
  5       amount         number(10)
  6    )
  7    PARTITION BY RANGE (yyyy, mm)
  8    (
  9      PARTITION p01 VALUES LESS THAN (2010,02),
 10      PARTITION p02 VALUES LESS THAN (2010,03),
 11      PARTITION p03 VALUES LESS THAN (2010,04)
         ...
         ...
 22    )
 23    /

Table created.



                                                     78
tiebreaker




             79
not multi dimension




                      80
SQL>   create table MOBILE_PHONE
  2    ( start_day      date not null,
  3      end_day        date not null,
  4      account_id     varchar2(10) not null,
  5      calls          number(10)
  6    )
  7    PARTITION BY RANGE (start_day, end_day)
  8    (
  9      PARTITION p01 VALUES LESS THAN
 10         ('01-FEB-2010','01-FEB-2010'),
 11      PARTITION p02 VALUES LESS THAN
 12         ('01-MAR-2010','01-MAR-2010'),
 13      PARTITION p03 VALUES LESS THAN
 14         ('01-APR-2010','01-APR-2010')
 15    )
 16    /

Table created.


                                                 81
SQL> select sum(calls)
  2 from    MOBILE_PHONE
  3 where START_DAY= '12-FEB-2010';

----------------------------------------------------------------
| Id | Operation                | Name         | Pstart| Pstop |
----------------------------------------------------------------
|   0 | SELECT STATEMENT        |              |       |       |
|   1 | SORT AGGREGATE          |              |       |       |
|   2 |   PARTITION RANGE SINGLE|              |     3 |     3 |
|* 3 |     TABLE ACCESS FULL    | MOBILE_PHONE |     3 |     3 |
----------------------------------------------------------------




                                                                   82
SQL> select sum(calls)
  2 from    MOBILE_PHONE
  3 where END_DAY= '12-FEB-2010';

----------------------------------------------------------------------
| Id | Operation                      | Name         | Pstart| Pstop |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT              |              |       |       |
|   1 | SORT AGGREGATE                |              |       |       |
|   2 |   PARTITION RANGE ALL         |              | 1     | 3     |
|* 3 |     TABLE ACCESS FULL          | MOBILE_PHONE | 1     | 3     |
----------------------------------------------------------------------




                                                                     83
9    PARTITION p01 VALUES LESS THAN
  10       ('01-FEB-2010','01-FEB-2010'),
  11    PARTITION p02 VALUES LESS THAN
  12       ('01-MAR-2010','01-MAR-2010'),
  13    PARTITION p03 VALUES LESS THAN
  14       ('01-APR-2010','01-APR-2010')




SQL> insert into MOBILE_PHONE
  2 values ('07-FEB-2010','12-FEB-2010');



SQL> insert into MOBILE_PHONE
  2 values ('23-JAN-2010','12-FEB-2010');


SQL> insert into MOBILE_PHONE
  2 values ('17-MAR-2010','12-FEB-2010');

                                            84
better in 11g




                85
SQL> select sum(calls)
  2 from    MOBILE_PHONE
  3 where END_DAY= '12-FEB-2010';

----------------------------------------------------------------------
| Id | Operation                      | Name         | Pstart| Pstop |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT              |              |       |       |
|   1 | SORT AGGREGATE                |              |       |       |
|   2 |   PARTITION RANGE MULTI-COLUMN|              |KEY(MC)|KEY(MC)|
|* 3 |     TABLE ACCESS FULL          | MOBILE_PHONE |KEY(MC)|KEY(MC)|
----------------------------------------------------------------------




                                                                     86
hash partitioning


           since 8.1

                       87
big stuff is a pain




                      88
"metapoor"




             89
possible benefits




                    92
manageability




                93
94
move

backup

 etc



         95
insertion
performance




              96
"buffer busy waits"




                      97
"enq: HW - contention"




                         98
"read by other session"




                          99
100
less relevant nowadays



                 for tables

                              101
ASSM




       102
automatic

 segment

  space

management

             103
SQL>   CREATE TABLESPACE DEMO
  2    DATAFILE '...' SIZE 20G
  3    EXTENT MANAGEMENT LOCAL
  4    SEGMENT SPACE MANAGEMENT AUTO;




                                        104
105
...but still very important


                 see later

                              106
SQL> create table T
  2   ( x number(10) )
  3   partition by hash ( x )
  4   partitions 8
  5 /

Table created.




                                107
even spread of values




                        108
SQL> create table T
  2   ( x number(10) )
  3   partition by hash ( x )
  4   partitions 8
  5 /

Table created.
                         1,2,3,4 .... 100000
SQL>   insert into T
  2    select level
  3    from dual connect by level <= 100000
  4    /

100000 rows created.

                                               109
SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by DBMS_ROWID.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     72166      12381
     72167      12628
     72161      12603
     72162      12574
     72163      12581
     72168      12382
     72164      12508
     72165      12342


                                                  110
predicting hash target




                         111
SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  SQL> select ora_hash(x,7), count(*)
  4 2 from t dbms_rowid.ROWID_OBJECT(rowid)
     group by
  5 3 group by ora_hash(x,7)
     order by 2;
    4 order by 2;
       PTN   COUNT(*)
---------- ----------
  ORA_HASH(X,7)     COUNT(*)
  ------------- 12342
     73535        ----------
     73536     4 12381 12342
     73538     5 12382 12381 remember these
     73534     7 12508 12382
     73532     3 12574 12508
     73533     1 12581 12574
     73531     2 12603 12581
     73537     0 12628 12603
               6       12628


                                                  112
the power of 2 rule




                      113
SQL> create table T
  2   ( x number(10) )
  3   partition by hash ( x )
  4   partitions 4 | 8 | 16 | 32 ...
  5 /

Table created.




                                       114
SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by DBMS_ROWID.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     72166      12381
     72167      12628
     72161      12603
     72162      12574
     72163      12581
     72168      12382
     72164      12508
     72165      12342


                                                  115
SQL> create table T
  2   ( x number(10) )
  3   partition by hash ( x )
  4   partitions 5
  5 /

Table created.

SQL>   insert into T
  2    select level
  3    from dual connect by level <= 100000
  4    /

100000 rows created.

                                              116
SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by DBMS_ROWID.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     72174      12342
     72172      25209
     72171      24955
     72173      24890
     72170      12603




                                                  117
why ?




        118
deliberately


     for maintenance...

                          119
Task:

from 5 to 8 partitions




                         120
"classical" redistribution




                             121
"every" row moves




                    122
SQL> select count(*)
  2 from    T
  3 where ora_hash(x,4) != ora_hash(x,7);

  COUNT(*)
----------
     87564




                                            123
"smart" redistribution




                         124
SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by DBMS_ROWID.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     72174      12342
     72172      25209
     72171      24955
     72173      24890     pick one
     72170      12603

5 rows selected.




                                                  125
SQL> alter table T add partition;

Table altered.

SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by dbms_rowid.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     73515      25209
     73516      24890
     73517      12342
     73519      12381
     73518      12574
     73513      12603


                                                  126
SQL> alter table T add partition;

Table altered.

SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn,
  2         count(*)
  3 from T
  4 group by dbms_rowid.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     73516      24890
     73517      12342
     73519      12381
     73518      12574
     73521      12628
     73520      12581
     73513      12603

                                                  127
SQL> alter table T add partition;

Table altered.

SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn,
  2     count(*)
  3 from T
  4 group by dbms_rowid.ROWID_OBJECT(rowid);

       PTN   COUNT(*)
---------- ----------
     73517      12342
     73523      12382
     73522      12508
     73519      12381
     73518      12574
     73521      12628
     73520      12581
     73513      12603
                                                  128
only 1 partition "effort"




                            129
same for coalesce partition




                              130
handling a small number of values




                                    131
SQL> create table ...
      ...
  20     values less than   ('WB'),
  21     values less than   ('QLE'),
  22     values less than   ('SB'),
  23     values less than   ('VID'),




      range fiddly....




                                       132
SQL> select state, ora_hash(state,7) hash
  2 from AUST;

STATE   HASH
-----   ----
WA         2
SA         5
NSW        3
VIC        5

 hash ... poor distribution




                                            133
list


       version 9

                   134
SQL>   create table SALES_DATA
  2    ( sales_id       varchar2(10) not null,
  3      location       varchar2(3) not null,
  4      amount         number(10)
  5    )
  6    PARTITION BY LIST (location)
  7    (
  8     PARTITION NSW   VALUES ('NSW'),
  9     PARTITION WA    VALUES ('WA'),
 10     PARTITION QLD   VALUES ('QLD'),
 11     PARTITION SA    VALUES ('SA'),
 12     PARTITION VIC   VALUES ('VIC'),
 13     PARTITION TERR VALUES ('ACT','NT'),
 14     PARTITION DREGS VALUES (DEFAULT)
 15    )
 18    /

Table created.

                                                 135
think carefully on DEFAULT


            add versus split

                               136
sometimes one level is not enough




                                    137
138
139
ranges unevenly distributed




                              140
deletion of older data
2009
            2010
                     2011       2012




                                       141
composite partitions




                       142
composite (range + hash)


               since 8.1

                           143
SQL>   create table COMP
  2    ( tstamp       timestamp(6) not null,
  3      empno        number(10)   not null,
  4      ename        varchar2(10) not null,
  5      deptno       varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    SUBPARTITION BY LIST (deptno)
  9    (
 10      PARTITION p01 VALUES LESS THAN
 11          (TIMESTAMP' 2010-01-01 00:00:00')
 12                   (SUBPARTITION p01_d1 VALUES   (1),
 13                    SUBPARTITION p01_d2 VALUES   (2),
 14                    SUBPARTITION p01_d3 VALUES   (3),
 15                    SUBPARTITION p01_d4 VALUES   (4)),
 16      PARTITION p02 VALUES LESS THAN
 17          (TIMESTAMP' 2010-02-01 00:00:00')
 18                   (SUBPARTITION p02_d1 VALUES   (1),
 19                    SUBPARTITION p02_d2 VALUES   (2),
 20                    SUBPARTITION p02_d3 VALUES   (3),
 21                    SUBPARTITION p02_d4 VALUES   (4)),
         .....                                              144
30   PARTITION p11 VALUES LESS THAN
31       (TIMESTAMP' 2010-11-01 00:00:00')
32                (SUBPARTITION p01_d1 VALUES (1,2),
33                 SUBPARTITION p01_d2 VALUES (3,4),
34   PARTITION p12 VALUES LESS THAN
35       (TIMESTAMP' 2010-12-01 00:00:00')
36   PARTITION p13 VALUES LESS THAN
37       (TIMESTAMP' 2011-01-01 00:00:00')

     .....




                   recall: coalesce partition

                                                       145
long DDL .....




                 146
subpartition templates




                         147
SQL>   create table COMP
  2    ( tstamp         timestamp(6) not null,
  3       empno         number(10)   not null,
  4       ename         varchar2(10) not null,
  5       deptno        varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    SUBPARTITION BY LIST (deptno)
  9        SUBPARTITION TEMPLATE
 10           (SUBPARTITION d1 VALUES (1),
 11             SUBPARTITION d2 VALUES (2),
 12             SUBPARTITION d3 VALUES (3),        implicit
 13             SUBPARTITION d4 VALUES (4))        subpar's
 14    (
 15       PARTITION p01 VALUES LESS THAN
 16           (TIMESTAMP' 2010-01-01 00:00:00'),
 17       PARTITION p02 VALUES LESS THAN
 18           (TIMESTAMP' 2010-02-01 00:00:00'),
 19      ....

                                                          148
SQL> select partition_name pname,
  2         partition_position pos,
  3         high_value
  4 from    USER_TAB_PARTITIONS
  5 where table_name = 'COMP';

PNAME             POS HIGH_VALUE
---------- ---------- --------------------------------
P01                 1 TIMESTAMP' 2010-01-01 00:00:00'
P02                 2 TIMESTAMP' 2010-02-01 00:00:00'
P03                 3 TIMESTAMP' 2010-03-01 00:00:00'
P04                 4 TIMESTAMP' 2010-04-01 00:00:00'
P05                 5 TIMESTAMP' 2010-05-01 00:00:00'
P06                 6 TIMESTAMP' 2010-06-01 00:00:00'
P07                 7 TIMESTAMP' 2010-07-01 00:00:00'
P08                 8 TIMESTAMP' 2010-08-01 00:00:00'
...

                                                         149
SQL>   select subpartition_name pname,
  2           subpartition_position pos,
  3           high_value
  4    from   USER_TAB_SUBPARTITIONS
  5    where table_name = 'COMP'
  6    order by 1,2;

PNAME             POS HIGH_VALUE
---------- ---------- ----------------------
P01_D1              1 '1'
P01_D2              2 '2'
P01_D3              3 '3'
P01_D4              4 '4'
P02_D1              1 '1'
P02_D2              2 '2'
P02_D3              3 '3'
P02_D4              4 '4'
P03_D1              1 '1'     auto named for
...                          subpar templates
...
                                                150
partitions

logical or physical




                      151
composite (range + list)


               since 9

                           152
composite (anything + anything)


                  since 11

                                  153
interval partitioning


                 11g

                        154
the problem with ranges....




                              155
... they are a range




                       156
require maintenance




                      157
25    PARTITION p13 VALUES LESS THAN
  26        (TIMESTAMP' 2011-01-01 00:00:00')
  27 );




SQL> insert into DEMO
  2 values ( to_date('01-JAN-2014'), .... );

insert into DEMO
            *
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition




                                                            158
insurance policy




                   159
25    PARTITION p13 VALUES LESS THAN
 26        (TIMESTAMP' 2011-01-01 00:00:00')
 26    PARTITION pmax VALUES LESS THAN
 27        (MAXVALUE)
 28 );



                                     magic value

SQL> insert into DEMO
  2 values ( to_date('01-JAN-2014'), .... );

1 row created.




                                                   160
why MAXVALUE might hurt


        (part 1)

                          161
split not add




                162
SQL>   alter table DEMO split partition PMAX
  2    at ( TIMESTAMP' 2012-02-01 00:00:00')
  3    into ( partition p14, partition pmax )
  4    /

Table altered.




                                                163
hoping for empty partition




                             164
"fast split" partition




                         165
index hassles


         see later...

                        166
"solved" in 11g




                  167
168
interval partitioning




                        169
SQL>   create table DEMO
  2    ( tstamp        timestamp(6) not null,
  3       empno        number(10)   not null,
  4       ename        varchar2(10) not null,
  5       deptno       varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    INTERVAL( NUMTOYMINTERVAL(1,'MONTH'))
  9    (
 10       PARTITION P00 VALUES LESS THAN
 11              (TIMESTAMP' 2010-01-01 00:00:00')
 11    );

Table created.




                                                     170
partitions created as required




                                 171
SQL> select PARTITION_NAME, HIGH_VALUE
  2 from    user_tab_partitions
  3 where table_name = 'DEMO';

PARTITION_NAME            HIGH_VALUE
------------------------- --------------------------------
P00                       TIMESTAMP' 2010-01-01 00:00:00'

SQL> insert into DEMO
  2 values ( to_date('12-DEC-2011'),....);

1 row created.

SQL> select PARTITION_NAME, HIGH_VALUE
  2 from    user_tab_partitions
  3 where table_name = 'DEMO';

PARTITION_NAME              HIGH_VALUE
-------------------------   --------------------------------
P00                         TIMESTAMP' 2010-01-01 00:00:00'
SYS_P362                    TIMESTAMP' 2012-01-01 00:00:00'
                                                               172
gaps allowed




               173
range partition boundaries


        Length   Length   Length




                                   174
partition name control lost


                can rename....

                                 175
convert range to interval




                            176
original range version




SQL> alter table DEMO
 2      SET INTERVAL ( NUMTOYMINTERVAL(1,'MONTH') );

Table altered.




                                                       177
SQL> insert into DEMO
  2 values ( to_date('01-JAN-2017'),....);

1 row created.




                                             178
SQL> select partition_name pname,
  2         partition_position pos,
  3         high_value
  4 from    user_tab_partitions
  5 where table_name = 'DEMO';

PNAME               POS HIGH_VALUE
------------ ---------- --------------------------------
P01                   1 TIMESTAMP' 2010-01-01 00:00:00'
P02                   2 TIMESTAMP' 2010-02-01 00:00:00'
P03                   3 TIMESTAMP' 2010-03-01 00:00:00'
P04                   4 TIMESTAMP' 2010-04-01 00:00:00'
...
P10                  10 TIMESTAMP' 2010-10-01 00:00:00'
P11                  11 TIMESTAMP' 2010-11-01 00:00:00'
P12                  12 TIMESTAMP' 2010-12-01 00:00:00'
P13                  13 TIMESTAMP' 2011-01-01 00:00:00'
SYS_P1091            14 TIMESTAMP' 2017-02-01 00:00:00'




                                                           179
but be careful ...




                     180
hybrid



range   range   range   interval


                                   181
is it range or interval ?




                            182
SQL> desc DBA_TAB_PARTITIONS

     Name                    Null?      Type
     ----------------------- --------   ----------------
     TABLE_OWNER                        VARCHAR2(30)
     TABLE_NAME                         VARCHAR2(30)
     COMPOSITE                          VARCHAR2(3)
     PARTITION_NAME                     VARCHAR2(30)
     SUBPARTITION_COUNT                 NUMBER
     HIGH_VALUE                         LONG

?    HIGH_VALUE_LENGTH
     PARTITION_POSITION
     TABLESPACE_NAME
                                        NUMBER
                                        NUMBER
                                        VARCHAR2(30)
     ...
     LOGGING                            VARCHAR2(7)
     COMPRESSION                        VARCHAR2(8)
     COMPRESS_FOR                       VARCHAR2(18)
     NUM_ROWS                           NUMBER
     BUFFER_POOL                        VARCHAR2(7)
     GLOBAL_STATS                       VARCHAR2(3)
     USER_STATS                         VARCHAR2(3)
                                                           183
SQL>   select o.subname,
  2      decode(bitand(tp.flags,32768),
  3            32768,'YES','NO') interval
  4    from SYS.TABPART$ tp, SYS.OBJ$ o
  6    where tp.obj# = o.obj#
  6    and o.name = 'DEMO';

SUBNAME                          INT
------------------------------   ---
P01                              NO
P02                              NO
P03                              NO
P04                              NO
P05                              NO
...
P11                              NO
P12                              NO
P13                              NO
SYS_P1091                        YES

14 rows selected.
                                            184
fixed in 11.2




                185
high range value gets "stuck"




                                186
SQL> insert into DEMO
  2 values ( to_date('01-JAN-2017'),...);

1 row created.

SQL> insert into DEMO
  2 values ( to_date('01-JAN-2016'),...);

1 row created.




                                            187
SQL> select partition_name pname,
  2         partition_position pos,
  3         high_value
  4 from    user_tab_partitions
  5 where table_name = 'DEMO';

PNAME               POS HIGH_VALUE
------------ ---------- -------------------------------
P01                   1 TIMESTAMP' 2010-01-01 00:00:00'
P02                   2 TIMESTAMP' 2010-02-01 00:00:00'
P03                   3 TIMESTAMP' 2010-03-01 00:00:00'
P04                   4 TIMESTAMP' 2010-04-01 00:00:00'
...
P13                  13 TIMESTAMP' 2011-01-01 00:00:00'
SYS_P1112            14 TIMESTAMP' 2016-02-01 00:00:00'
SYS_P1111            15 TIMESTAMP' 2017-02-01 00:00:00'



                                                          188
SQL> alter table DEMO drop partition P01;

Table altered.

SQL> alter table DEMO drop partition P02;

Table altered.

SQL> alter table DEMO drop partition P13;
alter table DEMO drop partition P13
                                *
ERROR at line 1:
ORA-14758: Last partition in the range
           section cannot be dropped




                                            189
Length   Length   Length




                           190
workarounds (maybe) unpleasant....




                                     191
SQL> alter table DEMO set interval ( );

Table altered.

SQL> alter table DEMO
  2 set interval (NUMTOYMINTERVAL(1,'MONTH'));

Table altered.




                                                 192
SQL> alter table DEMO merge partitions
  2 for (TIMESTAMP' 2010-12-30 00:00:00'),
  3 for (TIMESTAMP' 2016-01-10 00:00:00');

Table altered.




                                             193
11.2




       194
SQL> alter table DEMO
  2 set interval (NUMTOYMINTERVAL(1,'MONTH'));

Table altered.




                                                 195
why MAXVALUE might hurt


        (part 2)

                          196
SQL>   create table DEMO
  2    ( tstamp       timestamp(6) not null,
  3      empno        number(10)   not null,
  4      ename        varchar2(10) not null,
  5      deptno       varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    (
  9      PARTITION p01 VALUES LESS THAN
 10          (TIMESTAMP' 2010-01-01 00:00:00'),

        ...

25         partition PMAX values less than (MAXVALUE)
26     )
27     /

Table created.


                                                        197
SQL> alter table DEMO
  2    set interval ( NUMTOYMINTERVAL(1,'MONTH') );

*
ERROR at line 1:
ORA-14759: SET INTERVAL is not legal on this table.




                                                      198
explain plan anomaly




                       199
INTERVAL = "1 million partitions"




                                    200
SQL>   create table DEMO
  2    ( tstamp        timestamp(6) not null,
  3       empno        number(10)   not null,
  4       ename        varchar2(10) not null,
  5       deptno       varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    INTERVAL( NUMTOYMINTERVAL(1,'MONTH'))
  9    (
 10       PARTITION P00 VALUES LESS THAN
 11          (TIMESTAMP' 2010-01-01 00:00:00')
 12    );

Table created.




                                                 201
SQL> select * from DEMO;


------------------------------------------------------------
| Id | Operation            | Name | Rows | Pstart| Pstop |
------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     1 |       |       |
|   1 | PARTITION RANGE ALL|       |     1 |     1 |1048575|
|   2 |   TABLE ACCESS FULL | DEMO |     1 |     1 |1048575|
------------------------------------------------------------




                                                               202
partitioned tables ...

the bigger picture




                         203
SALES
SQL> desc SALES
 Name                 Null?    Type
 -------------------- -------- --------------
 SALE_DATE            NOT NULL DATE
...


   2009       2010        2011         2012




           SALES_ITEMS
SQL> desc SALES_ITEMS
 Name                   Null?      Type
 --------------------   --------   -----------
 SALE_ID                NOT NULL   NUMBER(12)
 ITEM_ID                NOT NULL   NUMBER(12)
 ...
                                                 204
reference partitions


                   11g

                         205
SQL>   create table PARENT
  2    ( d date         not null,
  3       p number(10) not null,
  4       pad char(10)
  5    )
  6    PARTITION BY RANGE (d)
  7    (
  8       PARTITION p1 VALUES LESS   THAN   (   to_date('01-JAN-2010')),
  9       PARTITION p2 VALUES LESS   THAN   (   to_date('01-FEB-2010')),
 10       PARTITION p3 VALUES LESS   THAN   (   to_date('01-MAR-2010')),
 11       PARTITION p4 VALUES LESS   THAN   (   to_date('01-APR-2010')),
 12       PARTITION p5 VALUES LESS   THAN   (   to_date('01-MAY-2010')),
 13       PARTITION p6 VALUES LESS   THAN   (   to_date('01-JUN-2010')),
 14       PARTITION p7 VALUES LESS   THAN   (   to_date('01-JUL-2010')),
 15       PARTITION p8 VALUES LESS   THAN   (   to_date('01-AUG-2010')),
 16       PARTITION p9 VALUES LESS   THAN   (   to_date('01-SEP-2010'))
 17    );

Table created.

SQL> alter table PARENT add primary key ( p );

Table altered.


                                                                           206
SQL>   create table CHILD
  2    ( p number(10) not null,
  3      c number(10) not null,
  4      constraint CHILD_FK foreign key ( p )
  5        references PARENT (p)
  6        on delete cascade
  7    )
  8    PARTITION BY REFERENCE (CHILD_FK)
  9    /

Table created.




                                                 207
SQL>   insert into PARENT
  2    select sysdate+rownum, rownum, rownum
  3    from dual connect by level <= 100
  4    /

100 rows created.

SQL>   insert into CHILD
  2    select rownum, rownum
  3    from dual connect by level <= 100
  4    /

100 rows created.




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

PL/SQL procedure successfully completed.

SQL> select partition_name, num_rows
  2 from    USER_TAB_PARTITIONS
  3 where table_name = 'CHILD';

PARTITION_NAME                   NUM_ROWS
------------------------------ ----------
P1                                      0
P2                                      0
P3                                      0
P4                                      0
P5                                      9
P6                                     31
P7                                     30
P8                                     30
P9                                      0

                                                     209
seems good .... but




                      210
null

SQL> create table CHILD
  2 ( p number(10),
  3    c number(10),
  4    constraint CHILD_FK foreign key ( p )
  5      references PARENT (p)
  6 )
  7 PARTITION BY REFERENCE (CHILD_FK)
  8 /
PARTITION BY REFERENCE (CHILD_FK)
                        *
ERROR at line 7:
ORA-14652: reference partitioning foreign key is not supported




                                                                 211
SQL>   create table PARENT
  2    ( d date not null,
  3      p number(10) not null,
  4      pad char(10)
  5    )
  6    PARTITION BY RANGE (d)
  7    INTERVAL( NUMTOYMINTERVAL(1,'MONTH'))
  8    ( PARTITION VALUES LESS THAN ( to_date('01-JAN-2010')) );

Table created.

SQL> create table CHILD
  2 ( p number(10) not null,
  3    c number(10) not null,
  4    constraint CHILD_FK foreign key ( p )
  5       references PARENT (p)
  6       on delete cascade
  7 )
  8 PARTITION BY REFERENCE (CHILD_FK);
create table CHILD
*
ERROR at line 1:
ORA-14659: Partitioning method of the parent table is not supported


                                                                   212
but the following "works"....




                                213
SQL> alter table PARENT
  2    set INTERVAL( NUMTOYMINTERVAL(1,'MONTH'));

Table altered.

SQL> insert into PARENT values (sysdate+1000,-1,'x');

1 row created.

SQL> select partition_name
  2 from    user_tab_partitions
                                                pk=-1
  3 where table_name = 'PARENT';

PARTITION_NAME
------------------------------
SYS_P1196
P1
P2
P3
...


                                                        214
SQL> insert into CHILD values (-1,0);
insert into CHILD values (-1,0)
            *
ERROR at line 1:
ORA-14401: inserted partition key is outside
           specified partition




                                               215
dropping requires order




                          216
SQL> drop table PARENT;
drop table PARENT
           *
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by
           foreign keys


SQL> drop table PARENT cascade constraints;
drop table PARENT cascade constraints
           *
ERROR at line 1:
ORA-14656: cannot drop the parent of a reference-
partitioned table




                                                        217
Suboptimal Query when Gather Partition Stats on Reference Partitioned

Wrong Results In 11g On Reference Partitioned Table

ORA-7445[KKPAMDINFO] ON SELECT AGAINST A REFERENCE
PARTITIONED TABLE




            its a very new feature

Drop of reference partition not allowed (ORA-2266) with FK between siblings

UNIQUE INDEX NOT WORKING PROPERLY ON PARTITIONED BY
REFERENCE TABLE

ALLOW DROP PARTITION TO SUCCEED ON REFERENCED PARTITION
WITHOUT CORRUPTING DATA.
                                                                          218
Part 2

indexes on partitioned tables




                                219
220
SALES


  2009         2010           2011       2012




SQL> create index SALES_IX on SALES ( CUSTOMER );




                                                    221
2009   2010   2011   2012




                            222
"global" index




                 223
big....really big


         extended rowid

                          224
ILM issues




             225
2009         2010         2011         2012




SQL> alter table SALES drop partition SALES_2009




                                                   226
SQL> create index DEMO_IX on DEMO ( empno );

Index created.

SQL> select status
  2 from    user_indexes
  3 where index_name = 'DEMO_IX';

STATUS
--------
VALID

SQL> select * from DEMO where empno = 123;

---------------------------------------------------------------------
| Id | Operation                           | Name    |Pstart| Pstop |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |         |      |        |
|   1 | TABLE ACCESS BY GLOBAL INDEX ROWID| DEMO     |ROWID | ROWID |
|* 2 |    INDEX RANGE SCAN                 | DEMO_IX |      |        |
---------------------------------------------------------------------



                                                                         227
SQL> alter table DEMO drop partition P06;

Table altered.

SQL> select status
  2 from    user_indexes
  3 where index_name = 'DEMO_IX';

STATUS
--------
UNUSABLE

SQL> select * from DEMO where empno = 123;

------------------------------------------------------------
| Id | Operation            | Name | Rows | Pstart| Pstop |
------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |    50 |       |       |
|   1 | PARTITION RANGE ALL|       |    50 |     1 |    13 |
|* 2 |    TABLE ACCESS FULL | DEMO |    50 |     1 |    13 |
------------------------------------------------------------

                                                               228
SQL> select value
  2 from    v$parameter
  3 where name = 'skip_unusable_indexes';

VALUE
------------------------------
TRUE




                                            229
keep the index valid




                       230
2009         2010         2011         2012




SQL> alter table SALES drop partition SALES_2009
  2    update indexes;



                                                   231
undo


large delete


   redo

               232
merge

    split

similar issues

  exchange


                 233
an alternative




                 234
"local" index




                235
2009         2010         2011         2012




SQL> create index SALES_IX ON SALES ( CUSTOMER )
  2    LOCAL;



                                                   236
smaller chunks




                 237
smaller rowid's




                  238
2009         2010         2011         2012




SQL> alter table SALES drop partition SALES_2009;




                                                    239
SQL> create index DEMO_IX on DEMO ( empno ) LOCAL;

Index created.

SQL> select partition_name, status
  2 from    user_ind_partitions
  3 where index_name = 'DEMO_IX';

PARTITION_NAME                   STATUS
------------------------------   -------
P01                              USABLE
P02                              USABLE
P03                              USABLE
P04                              USABLE
P05                              USABLE
P06                              USABLE
P07                              USABLE
...



                                                     240
SQL> alter table DEMO drop partition P06;

Table altered.

SQL> select partition_name, status
  2 from    user_ind_partitions
  3 where index_name = 'DEMO_IX';

PARTITION_NAME                   STATUS
------------------------------   -------
P01                              USABLE
P02                              USABLE
P03                              USABLE
P04                              USABLE
P05                              USABLE
P06                              USABLE
P07                              USABLE
...


                                            241
awesome for ILM




                  242
handlng old data




                   243
2009         2010         2011         2012




SQL> alter table SALES move partition SALES_2009
  2    COMPRESS;



                                                   244
RMAN




   2009         2010         2011         2012




SQL> alter table SALES move partition SALES_2009
  2    TABLESPACE CRAPPY_OLD_DISK;

SQL> alter tablespace CRAPPY_OLD_DISK READ ONLY;

                                                   245
11.2 very cool




                 246
"segment-less" segments




                          247
2009         2010         2011         2012




SQL> alter index SALES_IX partition SALES_IX_2009
  2    UNUSABLE;



                                                    248
handlng new data




                   249
2010         2011   2013
                                     2012
                                     2013




SQL> alter table SALES exchange
  2 partition SALES_2013 with
  3 table NEW_SALES;


                                            250
local = good
global = bad




               252
NO !




       253
different "target audience"




                              254
SQL> create index SALES_IX on SALES ( CUSTOMER ) LOCAL;




     123           123          123           123




      2009         2010         2011         2012




             SQL> select *
               2 from SALES
               3 where CUSTOMER = 123;



                                                      255
can be much much worse...




                            256
WA    VIC        WA   VIC    WA    VIC   WA    VIC

  2009             2010        2011        2012
NSW   QLD       NSW   QLD    NSW   QLD   NSW   QLD




            SQL> select *
              2 from SALES
              3 where CUSTOMER = 123;



                                                     257
explain plan




               258
SQL> select * from SALES
  2 where CUSTOMER= 123;

----------------------------------------------------------------------
| Id | Operation                           | Name    |Pstart | Pstop |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |         |       |       |
|   1 | PARTITION RANGE ALL                |         |     1 |    13 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID| SALES   |     1 |    13 |
|* 3 |     INDEX RANGE SCAN                | SALES_IX|     1 |    13 |
----------------------------------------------------------------------




                                                                         259
SQL> create index SALES_IX on SALES ( CUSTOMER ) LOCAL;



                          123
                           123
                            123
                             123




      2009         2010            2011      2012




             SQL> select *
               2 from SALES
               3 where CUSTOMER = 123;



                                                      260
"so global for
index lookups then"....




                          261
NO !




       262
123




2009           2010         2011     2012




       SQL>   select *
         2    from SALES
         3    where CUSTOMER = 123
         4    and YEAR = 2010;


                                            263
careful design




                 264
application compromises



             eg unique keys

                              265
so far ... "equipartition"




                             266
SALES




SQL> create index SALES_IX ON SALES ( CUSTOMER )
  2    global
  3    partition by ....


                                                   267
2009           2010         2011        2012



SQL>   create index SALES_IX
  2    on SALES ( location, empno )
  3    global partition by range ( location )
  4    ( partition p0 values less than (1),
  6      partition p1 values less than (2),
         ...
12       partition pmax values less than (maxvalue)
13     );

Index created.                                        268
rare ....




            269
...one special case



                      10g+

                             270
hash partitioned index




                         271
recall: hash partitioned tables




                                  272
ASSM
concurrency




              273
indexes a problem




                    274
275
hash partitioned indexes




                           276
SQL>   create index SALES_PK on SALES( TXN_ID )
  2    global partition by hash ( TXN_ID )
  3    partitions 8
  4    /

Index created.




                                                  277
278
only for equality


          primary keys

                         279
beware the NOSORT




                    280
reference partitions and indexes




                                   281
SALES



2009   2010       2011       2012



       SALES_ITEMS



2009   2010           2011   2012

                                    282
take care with ILM




                     283
SQL> alter table PARENT drop partition P6;

Table altered.

SQL> select partition_name
  2 from    user_tab_partitions
  3 where table_name = 'CHILD';

PARTITION_NAME
------------------------------
P1
P2
P3
P4
P5
P7
P8
P9

                                             284
SQL> alter table PARENT truncate partition P7;
alter table PARENT truncate partition P7
            *
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by
           enabled foreign keys

SQL> alter table CHILD truncate partition P7;

Table truncated.

SQL> alter table PARENT truncate partition P7;

Table truncated.


                                           gap

                                                        285
SQL> select index_name, status from user_indexes;

INDEX_NAME                       STATUS
------------------------------   --------
PARENT_PK                        UNUSABLE
CHILD_PK                         UNUSABLE




                                                    286
exchange is difficult...




                           287
plus more restrictions.....




                              288
Part 3

partition queries




                    289
partition pruning




                    290
efficiency =

data required /

  data scanned



                  291
SQL> create table DEMO
  2  ( tstamp       timestamp(6) not null,
  3    empno        number(10)   not null,
  4    ename        varchar2(10) not null,
  5    deptno       varchar2(10) not null
  6  )
  7  PARTITION BY RANGE (TSTAMP)
  8  (
  9    PARTITION p01 VALUES LESS THAN
 10        (TIMESTAMP' 2010-01-01 00:00:00'),
 11    PARTITION p02 VALUES LESS THAN
 12        (TIMESTAMP' 2010-02-01 00:00:00'),
 13    PARTITION p03 VALUES LESS THAN
 14        (TIMESTAMP' 2010-03-01 00:00:00'),
     ...
     ...
 25    PARTITION p13 VALUES LESS THAN
 26        (TIMESTAMP' 2011-01-01 00:00:00')
 27 );

Table created.

                                                292
360 days

SQL>   insert /*+ APPEND */ into DEMO
  2    select trunc(sysdate,'YYYY')+rownum/( 1000000 / 360 ),
  3           rownum,
  4           rownum,
  5           mod(rownum,1000)
  6    from dual
  7    connect by level <= 1000000
  8    /

1000000 rows created.




                                                                293
SQL> select * from DEMO
  2 where TSTAMP = to_date('01-JUN-2010');

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     1 |       |       |
|   1 | PARTITION RANGE SINGLE|       |     1 |     7 |     7 |
|* 2 |    TABLE ACCESS FULL    | DEMO |     1 |     7 |     7 |
---------------------------------------------------------------




                                                                  294
SQL> select * from DEMO
  2 where TRUNC(TSTAMP) = to_date('01-JUN-2010');

------------------------------------------------------------
| Id | Operation            | Name | Rows | Pstart| Pstop |
------------------------------------------------------------
|   0 | SELECT STATEMENT    |      | 10000 |       |       |
|   1 | PARTITION RANGE ALL|       | 10000 |     1 |    13 |
|* 2 |    TABLE ACCESS FULL | DEMO | 10000 |     1 |    13 |
------------------------------------------------------------




                                                               295
static versus dynamic




                        296
SQL> select * from DEMO
  2 where TSTAMP = :b1;

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     1 |       |       |
|   1 | PARTITION RANGE SINGLE|       |     1 |   KEY |   KEY |
|* 2 |    TABLE ACCESS FULL    | DEMO |     1 |   KEY |   KEY |
---------------------------------------------------------------




                                                              297
lots of power


      varies by version

                          298
SQL> select * from DEMO
  2 where TSTAMP between    to_date('12-JAN-2010')
  3               and       to_date('07-FEB-2010')
  4   or   TSTAMP between   to_date('03-JUN-2010')
  5               and       to_date('06-AUG-2010');

-----------------------------------------------------------
| Id | Operation           | Name | Rows | Pstart| Pstop |
-----------------------------------------------------------
|   0 | SELECT STATEMENT   |      |   240K|       |       |
|   1 | PARTITION RANGE OR|       |   240K|KEY(OR)|KEY(OR)|
|* 2 |    TABLE ACCESS FULL| DEMO |   240K|KEY(OR)|KEY(OR)|
-----------------------------------------------------------




                                                              299
SQL> select * from DEMO
  2 where TSTAMP in (to_date('01-JUN-2010'),
  3                   to_date('01-DEC-2010'));

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     2 |       |       |
|   1 | PARTITION RANGE INLIST|       |     2 |KEY(I) |KEY(I) |
|* 2 |    TABLE ACCESS FULL    | DEMO |     2 |KEY(I) |KEY(I) |
---------------------------------------------------------------




                                                              300
limitations of explain plan




                              301
SQL> select * from DEMO
  2 where TSTAMP in (to_date('01-JUN-2010'),
  3                   to_date('01-DEC-2010'));

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     2 |       |       |
|   1 | PARTITION RANGE INLIST|       |     2 |KEY(I) |KEY(I) |
|* 2 |    TABLE ACCESS FULL    | DEMO |     2 |KEY(I) |KEY(I) |
---------------------------------------------------------------




   JUN      JUL      AUG      SEP      OCT       NOV      DEC




                                                                  302
July

SQL> alter table DEMO move partition P08 tablespace USERS;

Table altered.

SQL> alter tablespace USERS offline;

Tablespace altered.

SQL> select count(*) from DEMO
  2 where TSTAMP in (to_date('01-JUN-2010'),
  3                   to_date('01-DEC-2010'));

  COUNT(*)
----------
      1234




                                                             303
SQL> select count(*) from DEMO
  2 where TSTAMP in (to_date('01-JUN-2010'),
  3                   to_date('01-JUL-2010'));

select count(*) from DEMO
                     *
ERROR at line 1:
ORA-00376: file 4 cannot be read at this time
ORA-01110: data file 4: 'C:ORACLEDB11USERS01.DBF'




                                                       304
"NO OP" pruning




                  305
SQL> select * from DEMO
  2 where TSTAMP = to_date('01-JUN-2020');

--------------------------------------------------------------
| Id | Operation              | Name | Rows | Pstart| Pstop |
--------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |     1 |       |       |
|   1 | PARTITION RANGE EMPTY|       |     1 |INVALID|INVALID|
|* 2 |    TABLE ACCESS FULL   | DEMO |     1 |INVALID|INVALID|
--------------------------------------------------------------




                                                                 306
pruning lists




                307
SQL>   create table SALES
  2    ( sales_id       varchar2(10) not null,
  3      location       varchar2(3) not null,
  4      amount         number(10)
  5    )
  6    PARTITION BY LIST (location)
  7    (
  8     PARTITION NSW   VALUES ('NSW'),
  9     PARTITION WA    VALUES ('WA'),
 10     PARTITION QLD   VALUES ('QLD'),
 11     PARTITION SA    VALUES ('SA'),
 12     PARTITION VIC   VALUES ('VIC'),
 13     PARTITION TERR VALUES ('ACT','NT')
 14    )
 15    /

Table created.


                                                 308
SQL> select * from sales
  2 where location = 'WA';

---------------------------------------------------------------
| Id | Operation              | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT      |       |     1 |       |       |
|   1 | PARTITION LIST SINGLE|        |     1 | KEY |     KEY |
|   2 |   TABLE ACCESS FULL   | SALES |     1 |     2 |     2 |
---------------------------------------------------------------




                                                              309
SQL> select * from sales
  2 where location like 'S%';

---------------------------------------------------------------
| Id | Operation              | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT      |       |     1 |       |       |
|   1 | PARTITION LIST SINGLE|        |     1 | KEY |     KEY |
|   2 |   TABLE ACCESS FULL   | SALES |     1 |     4 |     4 |
---------------------------------------------------------------




                                                              310
SQL> select * from sales
  2 where location NOT in ('WA','NSW');

------------------------------------------------------------
| Id | Operation           | Name | Rows | Pstart| Pstop |
------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |       |       |
|   1 | PARTITION LIST ALL|        |     1 |     1 |     6 |
|* 2 |    TABLE ACCESS FULL| SALES |     1 |     1 |     6 |
------------------------------------------------------------




                                                               311
pruning composites




                     312
SQL>   create table COMP
  2    ( tstamp         timestamp(6) not null,
  3       empno         number(10)   not null,
  4       ename         varchar2(10) not null,
  5       deptno        varchar2(10) not null
  6    )
  7    PARTITION BY RANGE (TSTAMP)
  8    SUBPARTITION BY LIST (deptno)
  9        SUBPARTITION TEMPLATE
 10           (SUBPARTITION d1 VALUES (1),
 11             SUBPARTITION d2 VALUES (2),
 12             SUBPARTITION d3 VALUES (3),
 13             SUBPARTITION d4 VALUES (4))
 14    (
 15       PARTITION p01 VALUES LESS THAN
 16           (TIMESTAMP' 2010-01-01 00:00:00'),
 17       PARTITION p02 VALUES LESS THAN
 18           (TIMESTAMP' 2010-02-01 00:00:00'),
 19      ....

                                                   313
SQL> select * from COMP
  2 where TSTAMP = to_date('01-JUN-2010')
  3 and    DEPTNO = 2;

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |     1 |       |       |
|   1 | PARTITION RANGE SINGLE|       |     1 |     7 |     7 |
|   2 |   PARTITION LIST SINGLE|      |     1 |     2 |     2 |
|* 3 |     TABLE ACCESS FULL   | COMP |     1 |    26 |    26 |
---------------------------------------------------------------




                                                              314
SQL> select * from COMP
  2 where DEPTNO = 3;

---------------------------------------------------------------
| Id | Operation               | Name | Rows | Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |   250K|       |       |
|   1 | PARTITION RANGE ALL    |      |   250K|     1 |    13 |
|   2 |   PARTITION LIST SINGLE|      |   250K|     3 |     3 |
|   3 |    TABLE ACCESS FULL   | COMP |   250K|   KEY |   KEY |
---------------------------------------------------------------




                                                              315
pruning by subquery




                      316
SQL>   select e.deptno, max(d.empno)
  2    from DEMO d, scott.emp e
  3    where d.tstamp = e.hiredate
  4    and e.sal < 10000
  5    group by e.deptno;

-------------------------------------------------------------------
| Id | Operation                   | Name | Rows | Pstart| Pstop |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |    14 |       |       |
|   1 | HASH GROUP BY              |      |    14 |       |       |
|* 2 |    HASH JOIN                |      |    14 |       |       |
|* 3 |     TABLE ACCESS FULL       | EMP |     14 |       |       |
|   4 |    PARTITION RANGE SUBQUERY|      | 1000K|KEY(SQ)|KEY(SQ)|
|   5 |     TABLE ACCESS FULL      | DEMO | 1000K|KEY(SQ)|KEY(SQ)|
-------------------------------------------------------------------




                                                               317
11g


      maybe 10.2 ?

                     318
SQL>   select e.deptno, max(d.empno)
  2    from demo d, scott.emp e
  3    where d.tstamp = e.hiredate
  4    and e.sal < 10000
  5    group by e.deptno;

-----------------------------------------------------------------
| Id | Operation                      | Name    | Pstart| Pstop |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT              |         |       |       |
|   1 | HASH GROUP BY                 |         |       |       |
|* 2 |    HASH JOIN                   |         |       |       |
|   3 |    PART JOIN FILTER CREATE    | :BF0000 |       |       |
|* 4 |      TABLE ACCESS FULL         | EMP     |       |       |
|   5 |    PARTITION RANGE JOIN-FILTER|         |:BF0000|:BF0000|
|   6 |     TABLE ACCESS FULL         | DEMO    |:BF0000|:BF0000|
-----------------------------------------------------------------



                                                               319
|   3 |    PART JOIN FILTER CREATE    | :BF0000 |       |       |
|* 4 |      TABLE ACCESS FULL         | EMP     |       |       |
|   5 |    PARTITION RANGE JOIN-FILTER|         |:BF0000|:BF0000|
|   6 |     TABLE ACCESS FULL         | DEMO    |:BF0000|:BF0000|
-----------------------------------------------------------------



                            huh ?




                                                               320
bloom filters




                321
The Bloom filter...is a space-efficient
 probabilistic data structure that is
 used to test whether an element is
         a member of a set.

                           - Wikipedia

                                          322
wtf ?

        323
"b" bits
"h" hash functions




                     324
b0

            b1

       h1   b2

            b3
data   h2
            b4
       h3
            b5

            b6

            b7
                 325
b0

            b1

       h1   b2

            b3
data   h2
            b4
       h3
            b5

            b6

            b7
                 326
b0

            b1

       h1   b2

            b3
data   h2
            b4
       h3
            b5

            b6

            b7
                 327
b0

            b1

       h1   b2

            b3
data   h2
            b4
       h3
            b5

            b6

            b7
                 328
b0

            b1

       h1   b2

            b3
data   h2
            b4
       h3
            b5

            b6

            b7
                 329
b0

b1

b2   h1

b3
     h2   matching
b4         data?
     h3
b5

b6

b7
                 330
b0

         b1

         b2   h1

do the   b3
"real"        h2   matching
 work
         b4         data?
              h3
         b5

         b6

         b7
                          331
b0

         b1

         b2   h1

do the   b3
"real"        h2   matching
 work
         b4         data?
              h3
         b5

         b6

         b7
                          332
"meta-poor"




              333
334
335
"are you joking...try in 6 months"




                                     336
"yes, we have some"




                      337
338
false positives possible




                           339
false negatives impossible




                             340
they are here to stay....




                            341
SQL> alter session set "_bloom_filter_enabled" = false;

SQL> alter session set "_bloom_pruning_enabled" = false;




                                                           342
other partitioning benefits




                              343
partition wise join




                      344
SQL> select d.*, d2.*
  2 from DEMO d, DEMO2 d2
  3 where d.TSTAMP = d2.TSTAMP;

-------------------------------------------------------------
| Id | Operation            | Name | Rows | Pstart| Pstop |
-------------------------------------------------------------
|   0 | SELECT STATEMENT    |       | 1003K|        |       |
|   1 | PARTITION RANGE ALL|        | 1003K|      1 |    13 |
|* 2 |    HASH JOIN         |       | 1003K|        |       |
|   3 |    TABLE ACCESS FULL| DEMO | 1000K|       1 |    13 |
|   4 |    TABLE ACCESS FULL| DEMO2 | 1000K|      1 |    13 |
-------------------------------------------------------------




                                                                345
"big deal"




             346
meta-poor




            347
348
1000 cars north of Perth




1000 cars south of Perth
                           349
350
"replace damaged models
at the north yard with matching
  models from the south yard"




                                  351
352
SQL> select ...
  2 from NORTH n, SOUTH s
  3 where n.MODEL = s.MODEL

----------------------------------------------------------------
| Id | Operation                     | Name    | Pstart| Pstop |
----------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |       |       |
|* 1 | HASH JOIN                     |         |       |       |
|   3 |    PARTITION RANGE ALL       |         |     1 |     2 |
|   4 |      TABLE ACCESS FULL       | NORTH   |     1 |     2 |
|   5 |    PARTITION RANGE ALL       |         |     1 |     2 |
|   6 |      TABLE ACCESS FULL       | SOUTH   |     1 |     2 |
----------------------------------------------------------------




                                                              353
NORTH



        4WD   SMART CARS




SOUTH



        4WD   SMART CARS

                           354
partition wise join




                      355
SQL> select ...
  2 from NORTH n, SOUTH s
  3 where n.model = s.model

-------------------------------------------------------------
| Id | Operation            | Name | Rows | Pstart| Pstop |
-------------------------------------------------------------
|   0 | SELECT STATEMENT    |       | 1003K|        |       |
|   1 | PARTITION RANGE ALL|        | 1003K|      1 |     2 |
|* 2 |    HASH JOIN         |       | 1003K|        |       |
|   3 |    TABLE ACCESS FULL| NORTH | 1000K|      1 |     2 |
|   4 |    TABLE ACCESS FULL| SOUTH | 1000K|      1 |     2 |
-------------------------------------------------------------




                                                                356
great parallel benefits




                          357
SQL> select /*+ PARALLEL(n) PARALLEL(s) */                              ...
  2 from north n, south s
  3 where n.model = s.model

----------------------------------------------------------------------------------------------
| Id | Operation                     | Name     | Pstart| Pstop |    TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |       |       |        |      |            |
|   1 | PX COORDINATOR               |          |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)        | :TQ10001 |       |       | Q1,01 | P->S | QC (RAND) |
|* 3 |     HASH JOIN                 |          |       |       | Q1,01 | PCWP |             |
|   4 |     PX BLOCK ITERATOR        |          |     1 |     2 | Q1,01 | PCWC |             |
|   5 |      TABLE ACCESS FULL       | NORTH    |     1 |     2 | Q1,01 | PCWP |             |
|   6 |     BUFFER SORT              |          |       |       | Q1,01 | PCWC |             |
|   7 |      PX RECEIVE              |          |       |       | Q1,01 | PCWP |             |
|   8 |       PX SEND BROADCAST LOCAL| :TQ10000 |       |       | Q1,00 | P->P | BCST LOCAL |
|   9 |        PX BLOCK ITERATOR     |          |     1 |     2 | Q1,00 | PCWC |             |
| 10 |          TABLE ACCESS FULL    | SOUTH    |     1 |     2 | Q1,00 | PCWP |             |
----------------------------------------------------------------------------------------------




                                                                                                 358
Slave 1     Slave 2



NORTH



         4WD      SMART CARS




SOUTH



         4WD      SMART CARS
        Slave 3     Slave 4
                               359
partitions must match exactly




                                360
if not, better in 11g




                        361
fallback to bloom filter




                           362
SQL> select ...
  2 from NORTH n, SOUTH s
  3 where n.model = s.model

----------------------------------------------------------------
| Id | Operation                     | Name    | Pstart| Pstop |
----------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |       |       |
|* 1 | HASH JOIN                     |         |       |       |
|   2 |   PART JOIN FILTER CREATE    | :BF0000 |       |       |
|   3 |    PARTITION RANGE ALL       |         |     1 |     2 |
|   4 |     TABLE ACCESS FULL        | NORTH   |     1 |     2 |
|   5 |   PARTITION RANGE JOIN-FILTER|         |:BF0000|:BF0000|
|   6 |    TABLE ACCESS FULL         | SOUTH   |:BF0000|:BF0000|
----------------------------------------------------------------




                                                               363
if nececssary, brew your own



                 don't assume

                                364
365
wrap up




          366
all positive




               367
know the pitfalls




                    368
pitfalls # 1




               369
SQL> select * from v$option;

PARAMETER                                            VALUE
--------------------------------------------------   --------
Partitioning                                         TRUE
Objects                                              TRUE
Real Application Clusters                            TRUE
Advanced replication                                 TRUE
Bit-mapped indexes                                   TRUE
Connection multiplexing                              TRUE
Connection pooling                                   TRUE
Database queuing                                     TRUE
Incremental backup and recovery                      TRUE
Instead-of triggers                                  TRUE
Parallel backup and recovery                         TRUE
Parallel execution                                   TRUE
Parallel load                                        TRUE




                                                                370
even in EE




             372
worth the cost....




                     373
pitfalls # 2




               374
boundary cases


   constraint validation

                           375
boundary cases


   statistics gathering

                          376
boundary cases


          shared pool

                        377
boundary cases


   reference partitions

                          378
test with sql trace




                      379
Connor McDonald
    OracleDBA



                co.uk




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



              www.oracledba.co.uk                   381

Contenu connexe

Tendances

Tendances (19)

UKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsUKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tips
 
Performance tuning a quick intoduction
Performance tuning   a quick intoductionPerformance tuning   a quick intoduction
Performance tuning a quick intoduction
 
SQLQueries
SQLQueriesSQLQueries
SQLQueries
 
pstack, truss etc to understand deeper issues in Oracle database
pstack, truss etc to understand deeper issues in Oracle databasepstack, truss etc to understand deeper issues in Oracle database
pstack, truss etc to understand deeper issues in Oracle database
 
Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolest
 
Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010Riyaj: why optimizer_hates_my_sql_2010
Riyaj: why optimizer_hates_my_sql_2010
 
Tracking Data Updates in Real-time with Change Data Capture
Tracking Data Updates in Real-time with Change Data CaptureTracking Data Updates in Real-time with Change Data Capture
Tracking Data Updates in Real-time with Change Data Capture
 
Catalystの設定シナリオ(メモ段階)
Catalystの設定シナリオ(メモ段階)Catalystの設定シナリオ(メモ段階)
Catalystの設定シナリオ(メモ段階)
 
SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013SQL Tuning 101 - Sep 2013
SQL Tuning 101 - Sep 2013
 
Oracle12c For Developers
Oracle12c For DevelopersOracle12c For Developers
Oracle12c For Developers
 
Demystifying cost based optimization
Demystifying cost based optimizationDemystifying cost based optimization
Demystifying cost based optimization
 
MySQL Query tuning 101
MySQL Query tuning 101MySQL Query tuning 101
MySQL Query tuning 101
 
New features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionNew features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in action
 
12c for Developers - Feb 2014
12c for Developers - Feb 201412c for Developers - Feb 2014
12c for Developers - Feb 2014
 
Oracle 11g new features for developers
Oracle 11g new features for developersOracle 11g new features for developers
Oracle 11g new features for developers
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
Quick reference for cql
Quick reference for cqlQuick reference for cql
Quick reference for cql
 
12c Mini Lesson - Inline PLSQL from SQL
12c Mini Lesson - Inline PLSQL from SQL12c Mini Lesson - Inline PLSQL from SQL
12c Mini Lesson - Inline PLSQL from SQL
 
Quick Wins
Quick WinsQuick Wins
Quick Wins
 

En vedette

Statistics on Partitioned Objects
Statistics on Partitioned ObjectsStatistics on Partitioned Objects
Statistics on Partitioned Objects
Doug Burns
 
The performance of the Vietnamese monochord
The performance of the Vietnamese monochordThe performance of the Vietnamese monochord
The performance of the Vietnamese monochord
lequangtn
 
100632 p6 v7 tricks and traps
100632 p6 v7 tricks and traps100632 p6 v7 tricks and traps
100632 p6 v7 tricks and traps
InSync Conference
 
Insync 10 session maximize your jd edwards enterprise one investment with t...
Insync 10 session   maximize your jd edwards enterprise one investment with t...Insync 10 session   maximize your jd edwards enterprise one investment with t...
Insync 10 session maximize your jd edwards enterprise one investment with t...
InSync Conference
 
Lets Do It World, World Cleanup 2012 Brainstorming How To Start
Lets Do It World, World Cleanup 2012 Brainstorming How To StartLets Do It World, World Cleanup 2012 Brainstorming How To Start
Lets Do It World, World Cleanup 2012 Brainstorming How To Start
Martin Pold
 
Photo Presentation
Photo PresentationPhoto Presentation
Photo Presentation
lequangtn
 
Rotating and Tessellateing Web2 Tool Logos
Rotating and Tessellateing Web2 Tool LogosRotating and Tessellateing Web2 Tool Logos
Rotating and Tessellateing Web2 Tool Logos
Rhysj1
 
Ndevr & CSBP GHG Accounting Software
Ndevr & CSBP GHG Accounting SoftwareNdevr & CSBP GHG Accounting Software
Ndevr & CSBP GHG Accounting Software
InSync Conference
 
The vietnamese monochord's performance
The vietnamese monochord's performanceThe vietnamese monochord's performance
The vietnamese monochord's performance
lequangtn
 

En vedette (20)

Statistics on Partitioned Objects
Statistics on Partitioned ObjectsStatistics on Partitioned Objects
Statistics on Partitioned Objects
 
All on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor SharingAll on Adaptive and Extended Cursor Sharing
All on Adaptive and Extended Cursor Sharing
 
Takshilacorporate presentation
Takshilacorporate presentationTakshilacorporate presentation
Takshilacorporate presentation
 
The performance of the Vietnamese monochord
The performance of the Vietnamese monochordThe performance of the Vietnamese monochord
The performance of the Vietnamese monochord
 
Usa cpa prez
Usa cpa prezUsa cpa prez
Usa cpa prez
 
State of the Media: The Social Media Report
State of the Media: The Social Media ReportState of the Media: The Social Media Report
State of the Media: The Social Media Report
 
100632 p6 v7 tricks and traps
100632 p6 v7 tricks and traps100632 p6 v7 tricks and traps
100632 p6 v7 tricks and traps
 
D linsync10 fusaapps
D linsync10 fusaappsD linsync10 fusaapps
D linsync10 fusaapps
 
Cameron downing presentation
Cameron downing presentationCameron downing presentation
Cameron downing presentation
 
DipIFRS Examiner's Report - June 2011
DipIFRS Examiner's Report - June 2011DipIFRS Examiner's Report - June 2011
DipIFRS Examiner's Report - June 2011
 
Insync 10 session maximize your jd edwards enterprise one investment with t...
Insync 10 session   maximize your jd edwards enterprise one investment with t...Insync 10 session   maximize your jd edwards enterprise one investment with t...
Insync 10 session maximize your jd edwards enterprise one investment with t...
 
Lets Do It World, World Cleanup 2012 Brainstorming How To Start
Lets Do It World, World Cleanup 2012 Brainstorming How To StartLets Do It World, World Cleanup 2012 Brainstorming How To Start
Lets Do It World, World Cleanup 2012 Brainstorming How To Start
 
New CPA Exam Guide
New CPA Exam GuideNew CPA Exam Guide
New CPA Exam Guide
 
Photo Presentation
Photo PresentationPhoto Presentation
Photo Presentation
 
Syllabus, DipIFRS
Syllabus, DipIFRSSyllabus, DipIFRS
Syllabus, DipIFRS
 
Rotating and Tessellateing Web2 Tool Logos
Rotating and Tessellateing Web2 Tool LogosRotating and Tessellateing Web2 Tool Logos
Rotating and Tessellateing Web2 Tool Logos
 
Asian Games 1990
Asian Games 1990Asian Games 1990
Asian Games 1990
 
Ndevr & CSBP GHG Accounting Software
Ndevr & CSBP GHG Accounting SoftwareNdevr & CSBP GHG Accounting Software
Ndevr & CSBP GHG Accounting Software
 
The vietnamese monochord's performance
The vietnamese monochord's performanceThe vietnamese monochord's performance
The vietnamese monochord's performance
 
FM June2012 Paper
FM June2012 PaperFM June2012 Paper
FM June2012 Paper
 

Similaire à Connor McDonald Partitioning

11thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp0111thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp01
Karam Abuataya
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)
Hemant K Chitale
 
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Guatemala User Group
 
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
Hailey_Database_Performance_Made_Easy_through_Graphics.pdfHailey_Database_Performance_Made_Easy_through_Graphics.pdf
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
cookie1969
 

Similaire à Connor McDonald Partitioning (20)

UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL features
 
11thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp0111thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp01
 
Sangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesSangam 2019 - The Latest Features
Sangam 2019 - The Latest Features
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application Development
 
OpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersOpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developers
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer Disasters
 
Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)Oracle Diagnostics : Explain Plans (Simple)
Oracle Diagnostics : Explain Plans (Simple)
 
Sql queries
Sql queriesSql queries
Sql queries
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
 
OOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresOOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL features
 
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?
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
PoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expériencePoC Oracle Exadata - Retour d'expérience
PoC Oracle Exadata - Retour d'expérience
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX Developers
 
MySQL 5.5 Guide to InnoDB Status
MySQL 5.5 Guide to InnoDB StatusMySQL 5.5 Guide to InnoDB Status
MySQL 5.5 Guide to InnoDB Status
 
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
 
Managing Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
 
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
Hailey_Database_Performance_Made_Easy_through_Graphics.pdfHailey_Database_Performance_Made_Easy_through_Graphics.pdf
Hailey_Database_Performance_Made_Easy_through_Graphics.pdf
 
Quickly Locate Poorly Performing DB2 for z/OS Batch SQL
Quickly Locate Poorly Performing DB2 for z/OS Batch SQL Quickly Locate Poorly Performing DB2 for z/OS Batch SQL
Quickly Locate Poorly Performing DB2 for z/OS Batch SQL
 
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019  - 10 great sql featuresLatin America Tour 2019  - 10 great sql features
Latin America Tour 2019 - 10 great sql features
 

Plus de InSync Conference

IBM and Oracle Joint Solution Centre
IBM and Oracle Joint Solution CentreIBM and Oracle Joint Solution Centre
IBM and Oracle Joint Solution Centre
InSync Conference
 
In Sync Running Apps On Oracle
In Sync  Running Apps On OracleIn Sync  Running Apps On Oracle
In Sync Running Apps On Oracle
InSync Conference
 
Optim Insync10 Paul Griffin presentation
Optim Insync10 Paul Griffin presentationOptim Insync10 Paul Griffin presentation
Optim Insync10 Paul Griffin presentation
InSync Conference
 
Nswh Insync 2010 Ammar Customer Presentation
Nswh Insync 2010 Ammar Customer PresentationNswh Insync 2010 Ammar Customer Presentation
Nswh Insync 2010 Ammar Customer Presentation
InSync Conference
 
Insync10 IBM JDE Sol Ed Announcement
Insync10 IBM JDE Sol Ed AnnouncementInsync10 IBM JDE Sol Ed Announcement
Insync10 IBM JDE Sol Ed Announcement
InSync Conference
 
InSync10 Implement JDE Financial Analytics and Make Better Decisions
InSync10  Implement JDE Financial Analytics and Make Better DecisionsInSync10  Implement JDE Financial Analytics and Make Better Decisions
InSync10 Implement JDE Financial Analytics and Make Better Decisions
InSync Conference
 
Ebs operational reporting at santos evaluation, selection & implementation
Ebs operational reporting at santos evaluation, selection & implementationEbs operational reporting at santos evaluation, selection & implementation
Ebs operational reporting at santos evaluation, selection & implementation
InSync Conference
 
Santos change management utility, our alternative to application change manag...
Santos change management utility, our alternative to application change manag...Santos change management utility, our alternative to application change manag...
Santos change management utility, our alternative to application change manag...
InSync Conference
 

Plus de InSync Conference (20)

Frank munz oracle fusion middleware and aws cloud services in sync11
Frank munz oracle fusion middleware and aws cloud services in sync11Frank munz oracle fusion middleware and aws cloud services in sync11
Frank munz oracle fusion middleware and aws cloud services in sync11
 
Pythian MySQL - database for the web based economy
Pythian   MySQL - database for the web based economyPythian   MySQL - database for the web based economy
Pythian MySQL - database for the web based economy
 
IBM and Oracle Joint Solution Centre
IBM and Oracle Joint Solution CentreIBM and Oracle Joint Solution Centre
IBM and Oracle Joint Solution Centre
 
In Sync Running Apps On Oracle
In Sync  Running Apps On OracleIn Sync  Running Apps On Oracle
In Sync Running Apps On Oracle
 
P6 r8
P6 r8P6 r8
P6 r8
 
P6 analytics
P6 analyticsP6 analytics
P6 analytics
 
Upk presentation insync
Upk presentation insync Upk presentation insync
Upk presentation insync
 
Oracle Fusion Middleware for JD Edwards
Oracle Fusion Middleware for JD EdwardsOracle Fusion Middleware for JD Edwards
Oracle Fusion Middleware for JD Edwards
 
In sync10 grc_suite
In sync10 grc_suiteIn sync10 grc_suite
In sync10 grc_suite
 
In sync10 cliffgodwin-ebs-final
In sync10 cliffgodwin-ebs-finalIn sync10 cliffgodwin-ebs-final
In sync10 cliffgodwin-ebs-final
 
In sync10 cliffgodwin-appskeynote-final
In sync10 cliffgodwin-appskeynote-finalIn sync10 cliffgodwin-appskeynote-final
In sync10 cliffgodwin-appskeynote-final
 
Mnod linsync10 oba
Mnod linsync10 obaMnod linsync10 oba
Mnod linsync10 oba
 
D linsync10 ofa5yrs
D linsync10 ofa5yrsD linsync10 ofa5yrs
D linsync10 ofa5yrs
 
Optim Insync10 Paul Griffin presentation
Optim Insync10 Paul Griffin presentationOptim Insync10 Paul Griffin presentation
Optim Insync10 Paul Griffin presentation
 
Nswh Insync 2010 Ammar Customer Presentation
Nswh Insync 2010 Ammar Customer PresentationNswh Insync 2010 Ammar Customer Presentation
Nswh Insync 2010 Ammar Customer Presentation
 
Insync10 IBM JDE Sol Ed Announcement
Insync10 IBM JDE Sol Ed AnnouncementInsync10 IBM JDE Sol Ed Announcement
Insync10 IBM JDE Sol Ed Announcement
 
InSync10 Implement JDE Financial Analytics and Make Better Decisions
InSync10  Implement JDE Financial Analytics and Make Better DecisionsInSync10  Implement JDE Financial Analytics and Make Better Decisions
InSync10 Implement JDE Financial Analytics and Make Better Decisions
 
Life after upgrading to r12
Life after upgrading to r12Life after upgrading to r12
Life after upgrading to r12
 
Ebs operational reporting at santos evaluation, selection & implementation
Ebs operational reporting at santos evaluation, selection & implementationEbs operational reporting at santos evaluation, selection & implementation
Ebs operational reporting at santos evaluation, selection & implementation
 
Santos change management utility, our alternative to application change manag...
Santos change management utility, our alternative to application change manag...Santos change management utility, our alternative to application change manag...
Santos change management utility, our alternative to application change manag...
 

Dernier

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Connor McDonald Partitioning

  • 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
  • 6. 6
  • 7. why ? ...now 7
  • 9. 9
  • 10. 10
  • 12. 80's 12
  • 13. 13
  • 14. 14
  • 17. 20G 17
  • 18.
  • 20. Storage is expensive 20
  • 21. Archive 21
  • 22. 22
  • 23. 90's 23
  • 24. 24
  • 25. JBOD 25
  • 26. Storage is cheap ! 26
  • 27. Archive 27
  • 28. Archive 28
  • 29. 1992 1996 1999
  • 30. 30
  • 31. 00's 31
  • 32. disk is even cheaper.... 32
  • 33. 33
  • 34. ....but 34
  • 35.
  • 37. JBOD 37
  • 38. 38
  • 39. HBA Infiniband Filer Cache Fibre Channel etc 39
  • 40. Storage is cheap ! 40
  • 41. Storage Storage is is expensive cheap ! 41
  • 42. CEO 42
  • 43. brings us to today... 43
  • 44. ILM 44
  • 46. keep everything .... cheaply 46
  • 47. put the new stuff on good storage keep everything .... cheaply put the old stuff on crappy storage 47
  • 49. 49
  • 50. basics 50
  • 51. range partitioning since 8.0 51
  • 52. SALES 2009 2010 2011 2012 52
  • 54. "all applications are (time) windows on data" http://thehelsinkideclaration.blogspot.com/ 54
  • 56. time the most common 56
  • 57. SQL> create table DEMO 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 ( 9 PARTITION p01 VALUES LESS THAN 10 (TIMESTAMP' 2010-01-01 00:00:00'), 11 PARTITION p02 VALUES LESS THAN 12 (TIMESTAMP' 2010-02-01 00:00:00'), 13 PARTITION p03 VALUES LESS THAN 14 (TIMESTAMP' 2010-03-01 00:00:00'), ... ... 25 PARTITION p13 VALUES LESS THAN 26 (TIMESTAMP' 2011-01-01 00:00:00') 27 ); Table created. 57
  • 58. SQL> select partition_name pname, 2 partition_position pos, 3 high_value 4 from USER_TAB_PARTITIONS 5 where table_name = 'DEMO'; PNAME POS HIGH_VALUE ----- ---------- ------------------------------- P01 1 TIMESTAMP' 2010-01-01 00:00:00' P02 2 TIMESTAMP' 2010-02-01 00:00:00' P03 3 TIMESTAMP' 2010-03-01 00:00:00' P04 4 TIMESTAMP' 2010-04-01 00:00:00' P05 5 TIMESTAMP' 2010-05-01 00:00:00' P06 6 TIMESTAMP' 2010-06-01 00:00:00' P07 7 TIMESTAMP' 2010-07-01 00:00:00' P08 8 TIMESTAMP' 2010-08-01 00:00:00' P09 9 TIMESTAMP' 2010-09-01 00:00:00' P10 10 TIMESTAMP' 2010-10-01 00:00:00' P11 11 TIMESTAMP' 2010-11-01 00:00:00' P12 12 TIMESTAMP' 2010-12-01 00:00:00' P13 13 TIMESTAMP' 2011-01-01 00:00:00' 58
  • 60. split by upper bound 60
  • 61. P02 >= 2010-01-01 P02 < 2010-02-01 PARTITION p01 VALUES LESS THAN (TIMESTAMP' 2010-01-01 00:00:00'), PARTITION p02 VALUES LESS THAN (TIMESTAMP' 2010-02-01 00:00:00'), January not February 61
  • 65. SQL> set autotrace traceonly explain SQL> select * from DEMO 2 where TSTAMP = to_date('11-JUN-2010'); --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE SINGLE| | 1 | 7 | 7 | |* 2 | TABLE ACCESS FULL | DEMO | 1 | 7 | 7 | --------------------------------------------------------------- 65
  • 66. SQL> select partition_name pname, 2 partition_position pos, 3 high_value 4 from user_tab_partitions 5 where table_name = 'DEMO'; PNAME POS HIGH_VALUE ----- ---------- ------------------------------- P01 1 TIMESTAMP' 2010-01-01 00:00:00' P02 2 TIMESTAMP' 2010-02-01 00:00:00' P03 3 TIMESTAMP' 2010-03-01 00:00:00' P04 4 TIMESTAMP' 2010-04-01 00:00:00' P05 5 TIMESTAMP' 2010-05-01 00:00:00' P06 6 TIMESTAMP' 2010-06-01 00:00:00' P07 7 TIMESTAMP' 2010-07-01 00:00:00' P08 8 TIMESTAMP' 2010-08-01 00:00:00' P09 9 TIMESTAMP' 2010-09-01 00:00:00' P10 10 TIMESTAMP' 2010-10-01 00:00:00' P11 11 TIMESTAMP' 2010-11-01 00:00:00' P12 12 TIMESTAMP' 2010-12-01 00:00:00' P13 13 TIMESTAMP' 2011-01-01 00:00:00' 66
  • 69. SQL> explain plan for select .... SQL> select * 2 from table(dbms_xplan.display) 69
  • 70. SQL> select * 2 from table( 3 dbms_xplan.display( 4 format=>'PARTITION -COST -BYTES')); 70
  • 71. SQL> select * 2 from table(dbms_xplan.display_awr(...)) 71
  • 72. SQL> select ... SQL> select * 2 from table(dbms_xplan.display_cursor) 72
  • 73. SQL> select * 2 from table(dbms_xplan.display_plan_baseline) 73
  • 74. back to range partitioning 74
  • 75. add / drop move cache control maintenance rebuild backup / read-only compress 75
  • 76. partition loss availability recovery a little dubious.... 76
  • 78. SQL> create table SALES_DATA 2 ( yyyy number(4) not null, 3 mm number(2) not null, 4 sales_id varchar2(10) not null, 5 amount number(10) 6 ) 7 PARTITION BY RANGE (yyyy, mm) 8 ( 9 PARTITION p01 VALUES LESS THAN (2010,02), 10 PARTITION p02 VALUES LESS THAN (2010,03), 11 PARTITION p03 VALUES LESS THAN (2010,04) ... ... 22 ) 23 / Table created. 78
  • 81. SQL> create table MOBILE_PHONE 2 ( start_day date not null, 3 end_day date not null, 4 account_id varchar2(10) not null, 5 calls number(10) 6 ) 7 PARTITION BY RANGE (start_day, end_day) 8 ( 9 PARTITION p01 VALUES LESS THAN 10 ('01-FEB-2010','01-FEB-2010'), 11 PARTITION p02 VALUES LESS THAN 12 ('01-MAR-2010','01-MAR-2010'), 13 PARTITION p03 VALUES LESS THAN 14 ('01-APR-2010','01-APR-2010') 15 ) 16 / Table created. 81
  • 82. SQL> select sum(calls) 2 from MOBILE_PHONE 3 where START_DAY= '12-FEB-2010'; ---------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ---------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | SORT AGGREGATE | | | | | 2 | PARTITION RANGE SINGLE| | 3 | 3 | |* 3 | TABLE ACCESS FULL | MOBILE_PHONE | 3 | 3 | ---------------------------------------------------------------- 82
  • 83. SQL> select sum(calls) 2 from MOBILE_PHONE 3 where END_DAY= '12-FEB-2010'; ---------------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | SORT AGGREGATE | | | | | 2 | PARTITION RANGE ALL | | 1 | 3 | |* 3 | TABLE ACCESS FULL | MOBILE_PHONE | 1 | 3 | ---------------------------------------------------------------------- 83
  • 84. 9 PARTITION p01 VALUES LESS THAN 10 ('01-FEB-2010','01-FEB-2010'), 11 PARTITION p02 VALUES LESS THAN 12 ('01-MAR-2010','01-MAR-2010'), 13 PARTITION p03 VALUES LESS THAN 14 ('01-APR-2010','01-APR-2010') SQL> insert into MOBILE_PHONE 2 values ('07-FEB-2010','12-FEB-2010'); SQL> insert into MOBILE_PHONE 2 values ('23-JAN-2010','12-FEB-2010'); SQL> insert into MOBILE_PHONE 2 values ('17-MAR-2010','12-FEB-2010'); 84
  • 86. SQL> select sum(calls) 2 from MOBILE_PHONE 3 where END_DAY= '12-FEB-2010'; ---------------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | SORT AGGREGATE | | | | | 2 | PARTITION RANGE MULTI-COLUMN| |KEY(MC)|KEY(MC)| |* 3 | TABLE ACCESS FULL | MOBILE_PHONE |KEY(MC)|KEY(MC)| ---------------------------------------------------------------------- 86
  • 87. hash partitioning since 8.1 87
  • 88. big stuff is a pain 88
  • 90.
  • 91.
  • 94. 94
  • 98. "enq: HW - contention" 98
  • 99. "read by other session" 99
  • 100. 100
  • 101. less relevant nowadays for tables 101
  • 102. ASSM 102
  • 103. automatic segment space management 103
  • 104. SQL> CREATE TABLESPACE DEMO 2 DATAFILE '...' SIZE 20G 3 EXTENT MANAGEMENT LOCAL 4 SEGMENT SPACE MANAGEMENT AUTO; 104
  • 105. 105
  • 106. ...but still very important see later 106
  • 107. SQL> create table T 2 ( x number(10) ) 3 partition by hash ( x ) 4 partitions 8 5 / Table created. 107
  • 108. even spread of values 108
  • 109. SQL> create table T 2 ( x number(10) ) 3 partition by hash ( x ) 4 partitions 8 5 / Table created. 1,2,3,4 .... 100000 SQL> insert into T 2 select level 3 from dual connect by level <= 100000 4 / 100000 rows created. 109
  • 110. SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by DBMS_ROWID.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 72166 12381 72167 12628 72161 12603 72162 12574 72163 12581 72168 12382 72164 12508 72165 12342 110
  • 112. SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T SQL> select ora_hash(x,7), count(*) 4 2 from t dbms_rowid.ROWID_OBJECT(rowid) group by 5 3 group by ora_hash(x,7) order by 2; 4 order by 2; PTN COUNT(*) ---------- ---------- ORA_HASH(X,7) COUNT(*) ------------- 12342 73535 ---------- 73536 4 12381 12342 73538 5 12382 12381 remember these 73534 7 12508 12382 73532 3 12574 12508 73533 1 12581 12574 73531 2 12603 12581 73537 0 12628 12603 6 12628 112
  • 113. the power of 2 rule 113
  • 114. SQL> create table T 2 ( x number(10) ) 3 partition by hash ( x ) 4 partitions 4 | 8 | 16 | 32 ... 5 / Table created. 114
  • 115. SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by DBMS_ROWID.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 72166 12381 72167 12628 72161 12603 72162 12574 72163 12581 72168 12382 72164 12508 72165 12342 115
  • 116. SQL> create table T 2 ( x number(10) ) 3 partition by hash ( x ) 4 partitions 5 5 / Table created. SQL> insert into T 2 select level 3 from dual connect by level <= 100000 4 / 100000 rows created. 116
  • 117. SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by DBMS_ROWID.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 72174 12342 72172 25209 72171 24955 72173 24890 72170 12603 117
  • 118. why ? 118
  • 119. deliberately for maintenance... 119
  • 120. Task: from 5 to 8 partitions 120
  • 123. SQL> select count(*) 2 from T 3 where ora_hash(x,4) != ora_hash(x,7); COUNT(*) ---------- 87564 123
  • 125. SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by DBMS_ROWID.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 72174 12342 72172 25209 72171 24955 72173 24890 pick one 72170 12603 5 rows selected. 125
  • 126. SQL> alter table T add partition; Table altered. SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by dbms_rowid.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 73515 25209 73516 24890 73517 12342 73519 12381 73518 12574 73513 12603 126
  • 127. SQL> alter table T add partition; Table altered. SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by dbms_rowid.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 73516 24890 73517 12342 73519 12381 73518 12574 73521 12628 73520 12581 73513 12603 127
  • 128. SQL> alter table T add partition; Table altered. SQL> select dbms_rowid.ROWID_OBJECT(rowid) ptn, 2 count(*) 3 from T 4 group by dbms_rowid.ROWID_OBJECT(rowid); PTN COUNT(*) ---------- ---------- 73517 12342 73523 12382 73522 12508 73519 12381 73518 12574 73521 12628 73520 12581 73513 12603 128
  • 129. only 1 partition "effort" 129
  • 130. same for coalesce partition 130
  • 131. handling a small number of values 131
  • 132. SQL> create table ... ... 20 values less than ('WB'), 21 values less than ('QLE'), 22 values less than ('SB'), 23 values less than ('VID'), range fiddly.... 132
  • 133. SQL> select state, ora_hash(state,7) hash 2 from AUST; STATE HASH ----- ---- WA 2 SA 5 NSW 3 VIC 5 hash ... poor distribution 133
  • 134. list version 9 134
  • 135. SQL> create table SALES_DATA 2 ( sales_id varchar2(10) not null, 3 location varchar2(3) not null, 4 amount number(10) 5 ) 6 PARTITION BY LIST (location) 7 ( 8 PARTITION NSW VALUES ('NSW'), 9 PARTITION WA VALUES ('WA'), 10 PARTITION QLD VALUES ('QLD'), 11 PARTITION SA VALUES ('SA'), 12 PARTITION VIC VALUES ('VIC'), 13 PARTITION TERR VALUES ('ACT','NT'), 14 PARTITION DREGS VALUES (DEFAULT) 15 ) 18 / Table created. 135
  • 136. think carefully on DEFAULT add versus split 136
  • 137. sometimes one level is not enough 137
  • 138. 138
  • 139. 139
  • 141. deletion of older data 2009 2010 2011 2012 141
  • 143. composite (range + hash) since 8.1 143
  • 144. SQL> create table COMP 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 SUBPARTITION BY LIST (deptno) 9 ( 10 PARTITION p01 VALUES LESS THAN 11 (TIMESTAMP' 2010-01-01 00:00:00') 12 (SUBPARTITION p01_d1 VALUES (1), 13 SUBPARTITION p01_d2 VALUES (2), 14 SUBPARTITION p01_d3 VALUES (3), 15 SUBPARTITION p01_d4 VALUES (4)), 16 PARTITION p02 VALUES LESS THAN 17 (TIMESTAMP' 2010-02-01 00:00:00') 18 (SUBPARTITION p02_d1 VALUES (1), 19 SUBPARTITION p02_d2 VALUES (2), 20 SUBPARTITION p02_d3 VALUES (3), 21 SUBPARTITION p02_d4 VALUES (4)), ..... 144
  • 145. 30 PARTITION p11 VALUES LESS THAN 31 (TIMESTAMP' 2010-11-01 00:00:00') 32 (SUBPARTITION p01_d1 VALUES (1,2), 33 SUBPARTITION p01_d2 VALUES (3,4), 34 PARTITION p12 VALUES LESS THAN 35 (TIMESTAMP' 2010-12-01 00:00:00') 36 PARTITION p13 VALUES LESS THAN 37 (TIMESTAMP' 2011-01-01 00:00:00') ..... recall: coalesce partition 145
  • 148. SQL> create table COMP 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 SUBPARTITION BY LIST (deptno) 9 SUBPARTITION TEMPLATE 10 (SUBPARTITION d1 VALUES (1), 11 SUBPARTITION d2 VALUES (2), 12 SUBPARTITION d3 VALUES (3), implicit 13 SUBPARTITION d4 VALUES (4)) subpar's 14 ( 15 PARTITION p01 VALUES LESS THAN 16 (TIMESTAMP' 2010-01-01 00:00:00'), 17 PARTITION p02 VALUES LESS THAN 18 (TIMESTAMP' 2010-02-01 00:00:00'), 19 .... 148
  • 149. SQL> select partition_name pname, 2 partition_position pos, 3 high_value 4 from USER_TAB_PARTITIONS 5 where table_name = 'COMP'; PNAME POS HIGH_VALUE ---------- ---------- -------------------------------- P01 1 TIMESTAMP' 2010-01-01 00:00:00' P02 2 TIMESTAMP' 2010-02-01 00:00:00' P03 3 TIMESTAMP' 2010-03-01 00:00:00' P04 4 TIMESTAMP' 2010-04-01 00:00:00' P05 5 TIMESTAMP' 2010-05-01 00:00:00' P06 6 TIMESTAMP' 2010-06-01 00:00:00' P07 7 TIMESTAMP' 2010-07-01 00:00:00' P08 8 TIMESTAMP' 2010-08-01 00:00:00' ... 149
  • 150. SQL> select subpartition_name pname, 2 subpartition_position pos, 3 high_value 4 from USER_TAB_SUBPARTITIONS 5 where table_name = 'COMP' 6 order by 1,2; PNAME POS HIGH_VALUE ---------- ---------- ---------------------- P01_D1 1 '1' P01_D2 2 '2' P01_D3 3 '3' P01_D4 4 '4' P02_D1 1 '1' P02_D2 2 '2' P02_D3 3 '3' P02_D4 4 '4' P03_D1 1 '1' auto named for ... subpar templates ... 150
  • 152. composite (range + list) since 9 152
  • 153. composite (anything + anything) since 11 153
  • 155. the problem with ranges.... 155
  • 156. ... they are a range 156
  • 158. 25 PARTITION p13 VALUES LESS THAN 26 (TIMESTAMP' 2011-01-01 00:00:00') 27 ); SQL> insert into DEMO 2 values ( to_date('01-JAN-2014'), .... ); insert into DEMO * ERROR at line 1: ORA-14400: inserted partition key does not map to any partition 158
  • 160. 25 PARTITION p13 VALUES LESS THAN 26 (TIMESTAMP' 2011-01-01 00:00:00') 26 PARTITION pmax VALUES LESS THAN 27 (MAXVALUE) 28 ); magic value SQL> insert into DEMO 2 values ( to_date('01-JAN-2014'), .... ); 1 row created. 160
  • 161. why MAXVALUE might hurt (part 1) 161
  • 163. SQL> alter table DEMO split partition PMAX 2 at ( TIMESTAMP' 2012-02-01 00:00:00') 3 into ( partition p14, partition pmax ) 4 / Table altered. 163
  • 164. hoping for empty partition 164
  • 166. index hassles see later... 166
  • 168. 168
  • 170. SQL> create table DEMO 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 INTERVAL( NUMTOYMINTERVAL(1,'MONTH')) 9 ( 10 PARTITION P00 VALUES LESS THAN 11 (TIMESTAMP' 2010-01-01 00:00:00') 11 ); Table created. 170
  • 171. partitions created as required 171
  • 172. SQL> select PARTITION_NAME, HIGH_VALUE 2 from user_tab_partitions 3 where table_name = 'DEMO'; PARTITION_NAME HIGH_VALUE ------------------------- -------------------------------- P00 TIMESTAMP' 2010-01-01 00:00:00' SQL> insert into DEMO 2 values ( to_date('12-DEC-2011'),....); 1 row created. SQL> select PARTITION_NAME, HIGH_VALUE 2 from user_tab_partitions 3 where table_name = 'DEMO'; PARTITION_NAME HIGH_VALUE ------------------------- -------------------------------- P00 TIMESTAMP' 2010-01-01 00:00:00' SYS_P362 TIMESTAMP' 2012-01-01 00:00:00' 172
  • 173. gaps allowed 173
  • 174. range partition boundaries Length Length Length 174
  • 175. partition name control lost can rename.... 175
  • 176. convert range to interval 176
  • 177. original range version SQL> alter table DEMO 2 SET INTERVAL ( NUMTOYMINTERVAL(1,'MONTH') ); Table altered. 177
  • 178. SQL> insert into DEMO 2 values ( to_date('01-JAN-2017'),....); 1 row created. 178
  • 179. SQL> select partition_name pname, 2 partition_position pos, 3 high_value 4 from user_tab_partitions 5 where table_name = 'DEMO'; PNAME POS HIGH_VALUE ------------ ---------- -------------------------------- P01 1 TIMESTAMP' 2010-01-01 00:00:00' P02 2 TIMESTAMP' 2010-02-01 00:00:00' P03 3 TIMESTAMP' 2010-03-01 00:00:00' P04 4 TIMESTAMP' 2010-04-01 00:00:00' ... P10 10 TIMESTAMP' 2010-10-01 00:00:00' P11 11 TIMESTAMP' 2010-11-01 00:00:00' P12 12 TIMESTAMP' 2010-12-01 00:00:00' P13 13 TIMESTAMP' 2011-01-01 00:00:00' SYS_P1091 14 TIMESTAMP' 2017-02-01 00:00:00' 179
  • 180. but be careful ... 180
  • 181. hybrid range range range interval 181
  • 182. is it range or interval ? 182
  • 183. SQL> desc DBA_TAB_PARTITIONS Name Null? Type ----------------------- -------- ---------------- TABLE_OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) COMPOSITE VARCHAR2(3) PARTITION_NAME VARCHAR2(30) SUBPARTITION_COUNT NUMBER HIGH_VALUE LONG ? HIGH_VALUE_LENGTH PARTITION_POSITION TABLESPACE_NAME NUMBER NUMBER VARCHAR2(30) ... LOGGING VARCHAR2(7) COMPRESSION VARCHAR2(8) COMPRESS_FOR VARCHAR2(18) NUM_ROWS NUMBER BUFFER_POOL VARCHAR2(7) GLOBAL_STATS VARCHAR2(3) USER_STATS VARCHAR2(3) 183
  • 184. SQL> select o.subname, 2 decode(bitand(tp.flags,32768), 3 32768,'YES','NO') interval 4 from SYS.TABPART$ tp, SYS.OBJ$ o 6 where tp.obj# = o.obj# 6 and o.name = 'DEMO'; SUBNAME INT ------------------------------ --- P01 NO P02 NO P03 NO P04 NO P05 NO ... P11 NO P12 NO P13 NO SYS_P1091 YES 14 rows selected. 184
  • 186. high range value gets "stuck" 186
  • 187. SQL> insert into DEMO 2 values ( to_date('01-JAN-2017'),...); 1 row created. SQL> insert into DEMO 2 values ( to_date('01-JAN-2016'),...); 1 row created. 187
  • 188. SQL> select partition_name pname, 2 partition_position pos, 3 high_value 4 from user_tab_partitions 5 where table_name = 'DEMO'; PNAME POS HIGH_VALUE ------------ ---------- ------------------------------- P01 1 TIMESTAMP' 2010-01-01 00:00:00' P02 2 TIMESTAMP' 2010-02-01 00:00:00' P03 3 TIMESTAMP' 2010-03-01 00:00:00' P04 4 TIMESTAMP' 2010-04-01 00:00:00' ... P13 13 TIMESTAMP' 2011-01-01 00:00:00' SYS_P1112 14 TIMESTAMP' 2016-02-01 00:00:00' SYS_P1111 15 TIMESTAMP' 2017-02-01 00:00:00' 188
  • 189. SQL> alter table DEMO drop partition P01; Table altered. SQL> alter table DEMO drop partition P02; Table altered. SQL> alter table DEMO drop partition P13; alter table DEMO drop partition P13 * ERROR at line 1: ORA-14758: Last partition in the range section cannot be dropped 189
  • 190. Length Length Length 190
  • 192. SQL> alter table DEMO set interval ( ); Table altered. SQL> alter table DEMO 2 set interval (NUMTOYMINTERVAL(1,'MONTH')); Table altered. 192
  • 193. SQL> alter table DEMO merge partitions 2 for (TIMESTAMP' 2010-12-30 00:00:00'), 3 for (TIMESTAMP' 2016-01-10 00:00:00'); Table altered. 193
  • 194. 11.2 194
  • 195. SQL> alter table DEMO 2 set interval (NUMTOYMINTERVAL(1,'MONTH')); Table altered. 195
  • 196. why MAXVALUE might hurt (part 2) 196
  • 197. SQL> create table DEMO 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 ( 9 PARTITION p01 VALUES LESS THAN 10 (TIMESTAMP' 2010-01-01 00:00:00'), ... 25 partition PMAX values less than (MAXVALUE) 26 ) 27 / Table created. 197
  • 198. SQL> alter table DEMO 2 set interval ( NUMTOYMINTERVAL(1,'MONTH') ); * ERROR at line 1: ORA-14759: SET INTERVAL is not legal on this table. 198
  • 200. INTERVAL = "1 million partitions" 200
  • 201. SQL> create table DEMO 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 INTERVAL( NUMTOYMINTERVAL(1,'MONTH')) 9 ( 10 PARTITION P00 VALUES LESS THAN 11 (TIMESTAMP' 2010-01-01 00:00:00') 12 ); Table created. 201
  • 202. SQL> select * from DEMO; ------------------------------------------------------------ | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE ALL| | 1 | 1 |1048575| | 2 | TABLE ACCESS FULL | DEMO | 1 | 1 |1048575| ------------------------------------------------------------ 202
  • 203. partitioned tables ... the bigger picture 203
  • 204. SALES SQL> desc SALES Name Null? Type -------------------- -------- -------------- SALE_DATE NOT NULL DATE ... 2009 2010 2011 2012 SALES_ITEMS SQL> desc SALES_ITEMS Name Null? Type -------------------- -------- ----------- SALE_ID NOT NULL NUMBER(12) ITEM_ID NOT NULL NUMBER(12) ... 204
  • 206. SQL> create table PARENT 2 ( d date not null, 3 p number(10) not null, 4 pad char(10) 5 ) 6 PARTITION BY RANGE (d) 7 ( 8 PARTITION p1 VALUES LESS THAN ( to_date('01-JAN-2010')), 9 PARTITION p2 VALUES LESS THAN ( to_date('01-FEB-2010')), 10 PARTITION p3 VALUES LESS THAN ( to_date('01-MAR-2010')), 11 PARTITION p4 VALUES LESS THAN ( to_date('01-APR-2010')), 12 PARTITION p5 VALUES LESS THAN ( to_date('01-MAY-2010')), 13 PARTITION p6 VALUES LESS THAN ( to_date('01-JUN-2010')), 14 PARTITION p7 VALUES LESS THAN ( to_date('01-JUL-2010')), 15 PARTITION p8 VALUES LESS THAN ( to_date('01-AUG-2010')), 16 PARTITION p9 VALUES LESS THAN ( to_date('01-SEP-2010')) 17 ); Table created. SQL> alter table PARENT add primary key ( p ); Table altered. 206
  • 207. SQL> create table CHILD 2 ( p number(10) not null, 3 c number(10) not null, 4 constraint CHILD_FK foreign key ( p ) 5 references PARENT (p) 6 on delete cascade 7 ) 8 PARTITION BY REFERENCE (CHILD_FK) 9 / Table created. 207
  • 208. SQL> insert into PARENT 2 select sysdate+rownum, rownum, rownum 3 from dual connect by level <= 100 4 / 100 rows created. SQL> insert into CHILD 2 select rownum, rownum 3 from dual connect by level <= 100 4 / 100 rows created. 208
  • 209. SQL> exec dbms_stats.gather_table_stats(user,'CHILD'); PL/SQL procedure successfully completed. SQL> select partition_name, num_rows 2 from USER_TAB_PARTITIONS 3 where table_name = 'CHILD'; PARTITION_NAME NUM_ROWS ------------------------------ ---------- P1 0 P2 0 P3 0 P4 0 P5 9 P6 31 P7 30 P8 30 P9 0 209
  • 210. seems good .... but 210
  • 211. null SQL> create table CHILD 2 ( p number(10), 3 c number(10), 4 constraint CHILD_FK foreign key ( p ) 5 references PARENT (p) 6 ) 7 PARTITION BY REFERENCE (CHILD_FK) 8 / PARTITION BY REFERENCE (CHILD_FK) * ERROR at line 7: ORA-14652: reference partitioning foreign key is not supported 211
  • 212. SQL> create table PARENT 2 ( d date not null, 3 p number(10) not null, 4 pad char(10) 5 ) 6 PARTITION BY RANGE (d) 7 INTERVAL( NUMTOYMINTERVAL(1,'MONTH')) 8 ( PARTITION VALUES LESS THAN ( to_date('01-JAN-2010')) ); Table created. SQL> create table CHILD 2 ( p number(10) not null, 3 c number(10) not null, 4 constraint CHILD_FK foreign key ( p ) 5 references PARENT (p) 6 on delete cascade 7 ) 8 PARTITION BY REFERENCE (CHILD_FK); create table CHILD * ERROR at line 1: ORA-14659: Partitioning method of the parent table is not supported 212
  • 213. but the following "works".... 213
  • 214. SQL> alter table PARENT 2 set INTERVAL( NUMTOYMINTERVAL(1,'MONTH')); Table altered. SQL> insert into PARENT values (sysdate+1000,-1,'x'); 1 row created. SQL> select partition_name 2 from user_tab_partitions pk=-1 3 where table_name = 'PARENT'; PARTITION_NAME ------------------------------ SYS_P1196 P1 P2 P3 ... 214
  • 215. SQL> insert into CHILD values (-1,0); insert into CHILD values (-1,0) * ERROR at line 1: ORA-14401: inserted partition key is outside specified partition 215
  • 217. SQL> drop table PARENT; drop table PARENT * ERROR at line 1: ORA-02449: unique/primary keys in table referenced by foreign keys SQL> drop table PARENT cascade constraints; drop table PARENT cascade constraints * ERROR at line 1: ORA-14656: cannot drop the parent of a reference- partitioned table 217
  • 218. Suboptimal Query when Gather Partition Stats on Reference Partitioned Wrong Results In 11g On Reference Partitioned Table ORA-7445[KKPAMDINFO] ON SELECT AGAINST A REFERENCE PARTITIONED TABLE its a very new feature Drop of reference partition not allowed (ORA-2266) with FK between siblings UNIQUE INDEX NOT WORKING PROPERLY ON PARTITIONED BY REFERENCE TABLE ALLOW DROP PARTITION TO SUCCEED ON REFERENCED PARTITION WITHOUT CORRUPTING DATA. 218
  • 219. Part 2 indexes on partitioned tables 219
  • 220. 220
  • 221. SALES 2009 2010 2011 2012 SQL> create index SALES_IX on SALES ( CUSTOMER ); 221
  • 222. 2009 2010 2011 2012 222
  • 224. big....really big extended rowid 224
  • 225. ILM issues 225
  • 226. 2009 2010 2011 2012 SQL> alter table SALES drop partition SALES_2009 226
  • 227. SQL> create index DEMO_IX on DEMO ( empno ); Index created. SQL> select status 2 from user_indexes 3 where index_name = 'DEMO_IX'; STATUS -------- VALID SQL> select * from DEMO where empno = 123; --------------------------------------------------------------------- | Id | Operation | Name |Pstart| Pstop | -------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | TABLE ACCESS BY GLOBAL INDEX ROWID| DEMO |ROWID | ROWID | |* 2 | INDEX RANGE SCAN | DEMO_IX | | | --------------------------------------------------------------------- 227
  • 228. SQL> alter table DEMO drop partition P06; Table altered. SQL> select status 2 from user_indexes 3 where index_name = 'DEMO_IX'; STATUS -------- UNUSABLE SQL> select * from DEMO where empno = 123; ------------------------------------------------------------ | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 50 | | | | 1 | PARTITION RANGE ALL| | 50 | 1 | 13 | |* 2 | TABLE ACCESS FULL | DEMO | 50 | 1 | 13 | ------------------------------------------------------------ 228
  • 229. SQL> select value 2 from v$parameter 3 where name = 'skip_unusable_indexes'; VALUE ------------------------------ TRUE 229
  • 230. keep the index valid 230
  • 231. 2009 2010 2011 2012 SQL> alter table SALES drop partition SALES_2009 2 update indexes; 231
  • 232. undo large delete redo 232
  • 233. merge split similar issues exchange 233
  • 236. 2009 2010 2011 2012 SQL> create index SALES_IX ON SALES ( CUSTOMER ) 2 LOCAL; 236
  • 239. 2009 2010 2011 2012 SQL> alter table SALES drop partition SALES_2009; 239
  • 240. SQL> create index DEMO_IX on DEMO ( empno ) LOCAL; Index created. SQL> select partition_name, status 2 from user_ind_partitions 3 where index_name = 'DEMO_IX'; PARTITION_NAME STATUS ------------------------------ ------- P01 USABLE P02 USABLE P03 USABLE P04 USABLE P05 USABLE P06 USABLE P07 USABLE ... 240
  • 241. SQL> alter table DEMO drop partition P06; Table altered. SQL> select partition_name, status 2 from user_ind_partitions 3 where index_name = 'DEMO_IX'; PARTITION_NAME STATUS ------------------------------ ------- P01 USABLE P02 USABLE P03 USABLE P04 USABLE P05 USABLE P06 USABLE P07 USABLE ... 241
  • 244. 2009 2010 2011 2012 SQL> alter table SALES move partition SALES_2009 2 COMPRESS; 244
  • 245. RMAN 2009 2010 2011 2012 SQL> alter table SALES move partition SALES_2009 2 TABLESPACE CRAPPY_OLD_DISK; SQL> alter tablespace CRAPPY_OLD_DISK READ ONLY; 245
  • 248. 2009 2010 2011 2012 SQL> alter index SALES_IX partition SALES_IX_2009 2 UNUSABLE; 248
  • 250. 2010 2011 2013 2012 2013 SQL> alter table SALES exchange 2 partition SALES_2013 with 3 table NEW_SALES; 250
  • 252. global = bad 252
  • 253. NO ! 253
  • 255. SQL> create index SALES_IX on SALES ( CUSTOMER ) LOCAL; 123 123 123 123 2009 2010 2011 2012 SQL> select * 2 from SALES 3 where CUSTOMER = 123; 255
  • 256. can be much much worse... 256
  • 257. WA VIC WA VIC WA VIC WA VIC 2009 2010 2011 2012 NSW QLD NSW QLD NSW QLD NSW QLD SQL> select * 2 from SALES 3 where CUSTOMER = 123; 257
  • 258. explain plan 258
  • 259. SQL> select * from SALES 2 where CUSTOMER= 123; ---------------------------------------------------------------------- | Id | Operation | Name |Pstart | Pstop | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | PARTITION RANGE ALL | | 1 | 13 | | 2 | TABLE ACCESS BY LOCAL INDEX ROWID| SALES | 1 | 13 | |* 3 | INDEX RANGE SCAN | SALES_IX| 1 | 13 | ---------------------------------------------------------------------- 259
  • 260. SQL> create index SALES_IX on SALES ( CUSTOMER ) LOCAL; 123 123 123 123 2009 2010 2011 2012 SQL> select * 2 from SALES 3 where CUSTOMER = 123; 260
  • 261. "so global for index lookups then".... 261
  • 262. NO ! 262
  • 263. 123 2009 2010 2011 2012 SQL> select * 2 from SALES 3 where CUSTOMER = 123 4 and YEAR = 2010; 263
  • 265. application compromises eg unique keys 265
  • 266. so far ... "equipartition" 266
  • 267. SALES SQL> create index SALES_IX ON SALES ( CUSTOMER ) 2 global 3 partition by .... 267
  • 268. 2009 2010 2011 2012 SQL> create index SALES_IX 2 on SALES ( location, empno ) 3 global partition by range ( location ) 4 ( partition p0 values less than (1), 6 partition p1 values less than (2), ... 12 partition pmax values less than (maxvalue) 13 ); Index created. 268
  • 269. rare .... 269
  • 270. ...one special case 10g+ 270
  • 275. 275
  • 277. SQL> create index SALES_PK on SALES( TXN_ID ) 2 global partition by hash ( TXN_ID ) 3 partitions 8 4 / Index created. 277
  • 278. 278
  • 279. only for equality primary keys 279
  • 281. reference partitions and indexes 281
  • 282. SALES 2009 2010 2011 2012 SALES_ITEMS 2009 2010 2011 2012 282
  • 283. take care with ILM 283
  • 284. SQL> alter table PARENT drop partition P6; Table altered. SQL> select partition_name 2 from user_tab_partitions 3 where table_name = 'CHILD'; PARTITION_NAME ------------------------------ P1 P2 P3 P4 P5 P7 P8 P9 284
  • 285. SQL> alter table PARENT truncate partition P7; alter table PARENT truncate partition P7 * ERROR at line 1: ORA-02266: unique/primary keys in table referenced by enabled foreign keys SQL> alter table CHILD truncate partition P7; Table truncated. SQL> alter table PARENT truncate partition P7; Table truncated. gap 285
  • 286. SQL> select index_name, status from user_indexes; INDEX_NAME STATUS ------------------------------ -------- PARENT_PK UNUSABLE CHILD_PK UNUSABLE 286
  • 291. efficiency = data required / data scanned 291
  • 292. SQL> create table DEMO 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 ( 9 PARTITION p01 VALUES LESS THAN 10 (TIMESTAMP' 2010-01-01 00:00:00'), 11 PARTITION p02 VALUES LESS THAN 12 (TIMESTAMP' 2010-02-01 00:00:00'), 13 PARTITION p03 VALUES LESS THAN 14 (TIMESTAMP' 2010-03-01 00:00:00'), ... ... 25 PARTITION p13 VALUES LESS THAN 26 (TIMESTAMP' 2011-01-01 00:00:00') 27 ); Table created. 292
  • 293. 360 days SQL> insert /*+ APPEND */ into DEMO 2 select trunc(sysdate,'YYYY')+rownum/( 1000000 / 360 ), 3 rownum, 4 rownum, 5 mod(rownum,1000) 6 from dual 7 connect by level <= 1000000 8 / 1000000 rows created. 293
  • 294. SQL> select * from DEMO 2 where TSTAMP = to_date('01-JUN-2010'); --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE SINGLE| | 1 | 7 | 7 | |* 2 | TABLE ACCESS FULL | DEMO | 1 | 7 | 7 | --------------------------------------------------------------- 294
  • 295. SQL> select * from DEMO 2 where TRUNC(TSTAMP) = to_date('01-JUN-2010'); ------------------------------------------------------------ | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 10000 | | | | 1 | PARTITION RANGE ALL| | 10000 | 1 | 13 | |* 2 | TABLE ACCESS FULL | DEMO | 10000 | 1 | 13 | ------------------------------------------------------------ 295
  • 297. SQL> select * from DEMO 2 where TSTAMP = :b1; --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE SINGLE| | 1 | KEY | KEY | |* 2 | TABLE ACCESS FULL | DEMO | 1 | KEY | KEY | --------------------------------------------------------------- 297
  • 298. lots of power varies by version 298
  • 299. SQL> select * from DEMO 2 where TSTAMP between to_date('12-JAN-2010') 3 and to_date('07-FEB-2010') 4 or TSTAMP between to_date('03-JUN-2010') 5 and to_date('06-AUG-2010'); ----------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | ----------------------------------------------------------- | 0 | SELECT STATEMENT | | 240K| | | | 1 | PARTITION RANGE OR| | 240K|KEY(OR)|KEY(OR)| |* 2 | TABLE ACCESS FULL| DEMO | 240K|KEY(OR)|KEY(OR)| ----------------------------------------------------------- 299
  • 300. SQL> select * from DEMO 2 where TSTAMP in (to_date('01-JUN-2010'), 3 to_date('01-DEC-2010')); --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | | | | 1 | PARTITION RANGE INLIST| | 2 |KEY(I) |KEY(I) | |* 2 | TABLE ACCESS FULL | DEMO | 2 |KEY(I) |KEY(I) | --------------------------------------------------------------- 300
  • 302. SQL> select * from DEMO 2 where TSTAMP in (to_date('01-JUN-2010'), 3 to_date('01-DEC-2010')); --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | | | | 1 | PARTITION RANGE INLIST| | 2 |KEY(I) |KEY(I) | |* 2 | TABLE ACCESS FULL | DEMO | 2 |KEY(I) |KEY(I) | --------------------------------------------------------------- JUN JUL AUG SEP OCT NOV DEC 302
  • 303. July SQL> alter table DEMO move partition P08 tablespace USERS; Table altered. SQL> alter tablespace USERS offline; Tablespace altered. SQL> select count(*) from DEMO 2 where TSTAMP in (to_date('01-JUN-2010'), 3 to_date('01-DEC-2010')); COUNT(*) ---------- 1234 303
  • 304. SQL> select count(*) from DEMO 2 where TSTAMP in (to_date('01-JUN-2010'), 3 to_date('01-JUL-2010')); select count(*) from DEMO * ERROR at line 1: ORA-00376: file 4 cannot be read at this time ORA-01110: data file 4: 'C:ORACLEDB11USERS01.DBF' 304
  • 306. SQL> select * from DEMO 2 where TSTAMP = to_date('01-JUN-2020'); -------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE EMPTY| | 1 |INVALID|INVALID| |* 2 | TABLE ACCESS FULL | DEMO | 1 |INVALID|INVALID| -------------------------------------------------------------- 306
  • 308. SQL> create table SALES 2 ( sales_id varchar2(10) not null, 3 location varchar2(3) not null, 4 amount number(10) 5 ) 6 PARTITION BY LIST (location) 7 ( 8 PARTITION NSW VALUES ('NSW'), 9 PARTITION WA VALUES ('WA'), 10 PARTITION QLD VALUES ('QLD'), 11 PARTITION SA VALUES ('SA'), 12 PARTITION VIC VALUES ('VIC'), 13 PARTITION TERR VALUES ('ACT','NT') 14 ) 15 / Table created. 308
  • 309. SQL> select * from sales 2 where location = 'WA'; --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION LIST SINGLE| | 1 | KEY | KEY | | 2 | TABLE ACCESS FULL | SALES | 1 | 2 | 2 | --------------------------------------------------------------- 309
  • 310. SQL> select * from sales 2 where location like 'S%'; --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION LIST SINGLE| | 1 | KEY | KEY | | 2 | TABLE ACCESS FULL | SALES | 1 | 4 | 4 | --------------------------------------------------------------- 310
  • 311. SQL> select * from sales 2 where location NOT in ('WA','NSW'); ------------------------------------------------------------ | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION LIST ALL| | 1 | 1 | 6 | |* 2 | TABLE ACCESS FULL| SALES | 1 | 1 | 6 | ------------------------------------------------------------ 311
  • 313. SQL> create table COMP 2 ( tstamp timestamp(6) not null, 3 empno number(10) not null, 4 ename varchar2(10) not null, 5 deptno varchar2(10) not null 6 ) 7 PARTITION BY RANGE (TSTAMP) 8 SUBPARTITION BY LIST (deptno) 9 SUBPARTITION TEMPLATE 10 (SUBPARTITION d1 VALUES (1), 11 SUBPARTITION d2 VALUES (2), 12 SUBPARTITION d3 VALUES (3), 13 SUBPARTITION d4 VALUES (4)) 14 ( 15 PARTITION p01 VALUES LESS THAN 16 (TIMESTAMP' 2010-01-01 00:00:00'), 17 PARTITION p02 VALUES LESS THAN 18 (TIMESTAMP' 2010-02-01 00:00:00'), 19 .... 313
  • 314. SQL> select * from COMP 2 where TSTAMP = to_date('01-JUN-2010') 3 and DEPTNO = 2; --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | | 1 | PARTITION RANGE SINGLE| | 1 | 7 | 7 | | 2 | PARTITION LIST SINGLE| | 1 | 2 | 2 | |* 3 | TABLE ACCESS FULL | COMP | 1 | 26 | 26 | --------------------------------------------------------------- 314
  • 315. SQL> select * from COMP 2 where DEPTNO = 3; --------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | --------------------------------------------------------------- | 0 | SELECT STATEMENT | | 250K| | | | 1 | PARTITION RANGE ALL | | 250K| 1 | 13 | | 2 | PARTITION LIST SINGLE| | 250K| 3 | 3 | | 3 | TABLE ACCESS FULL | COMP | 250K| KEY | KEY | --------------------------------------------------------------- 315
  • 317. SQL> select e.deptno, max(d.empno) 2 from DEMO d, scott.emp e 3 where d.tstamp = e.hiredate 4 and e.sal < 10000 5 group by e.deptno; ------------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | | | | 1 | HASH GROUP BY | | 14 | | | |* 2 | HASH JOIN | | 14 | | | |* 3 | TABLE ACCESS FULL | EMP | 14 | | | | 4 | PARTITION RANGE SUBQUERY| | 1000K|KEY(SQ)|KEY(SQ)| | 5 | TABLE ACCESS FULL | DEMO | 1000K|KEY(SQ)|KEY(SQ)| ------------------------------------------------------------------- 317
  • 318. 11g maybe 10.2 ? 318
  • 319. SQL> select e.deptno, max(d.empno) 2 from demo d, scott.emp e 3 where d.tstamp = e.hiredate 4 and e.sal < 10000 5 group by e.deptno; ----------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | 1 | HASH GROUP BY | | | | |* 2 | HASH JOIN | | | | | 3 | PART JOIN FILTER CREATE | :BF0000 | | | |* 4 | TABLE ACCESS FULL | EMP | | | | 5 | PARTITION RANGE JOIN-FILTER| |:BF0000|:BF0000| | 6 | TABLE ACCESS FULL | DEMO |:BF0000|:BF0000| ----------------------------------------------------------------- 319
  • 320. | 3 | PART JOIN FILTER CREATE | :BF0000 | | | |* 4 | TABLE ACCESS FULL | EMP | | | | 5 | PARTITION RANGE JOIN-FILTER| |:BF0000|:BF0000| | 6 | TABLE ACCESS FULL | DEMO |:BF0000|:BF0000| ----------------------------------------------------------------- huh ? 320
  • 322. The Bloom filter...is a space-efficient probabilistic data structure that is used to test whether an element is a member of a set. - Wikipedia 322
  • 323. wtf ? 323
  • 324. "b" bits "h" hash functions 324
  • 325. b0 b1 h1 b2 b3 data h2 b4 h3 b5 b6 b7 325
  • 326. b0 b1 h1 b2 b3 data h2 b4 h3 b5 b6 b7 326
  • 327. b0 b1 h1 b2 b3 data h2 b4 h3 b5 b6 b7 327
  • 328. b0 b1 h1 b2 b3 data h2 b4 h3 b5 b6 b7 328
  • 329. b0 b1 h1 b2 b3 data h2 b4 h3 b5 b6 b7 329
  • 330. b0 b1 b2 h1 b3 h2 matching b4 data? h3 b5 b6 b7 330
  • 331. b0 b1 b2 h1 do the b3 "real" h2 matching work b4 data? h3 b5 b6 b7 331
  • 332. b0 b1 b2 h1 do the b3 "real" h2 matching work b4 data? h3 b5 b6 b7 332
  • 333. "meta-poor" 333
  • 334. 334
  • 335. 335
  • 336. "are you joking...try in 6 months" 336
  • 337. "yes, we have some" 337
  • 338. 338
  • 341. they are here to stay.... 341
  • 342. SQL> alter session set "_bloom_filter_enabled" = false; SQL> alter session set "_bloom_pruning_enabled" = false; 342
  • 345. SQL> select d.*, d2.* 2 from DEMO d, DEMO2 d2 3 where d.TSTAMP = d2.TSTAMP; ------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1003K| | | | 1 | PARTITION RANGE ALL| | 1003K| 1 | 13 | |* 2 | HASH JOIN | | 1003K| | | | 3 | TABLE ACCESS FULL| DEMO | 1000K| 1 | 13 | | 4 | TABLE ACCESS FULL| DEMO2 | 1000K| 1 | 13 | ------------------------------------------------------------- 345
  • 346. "big deal" 346
  • 347. meta-poor 347
  • 348. 348
  • 349. 1000 cars north of Perth 1000 cars south of Perth 349
  • 350. 350
  • 351. "replace damaged models at the north yard with matching models from the south yard" 351
  • 352. 352
  • 353. SQL> select ... 2 from NORTH n, SOUTH s 3 where n.MODEL = s.MODEL ---------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ---------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | |* 1 | HASH JOIN | | | | | 3 | PARTITION RANGE ALL | | 1 | 2 | | 4 | TABLE ACCESS FULL | NORTH | 1 | 2 | | 5 | PARTITION RANGE ALL | | 1 | 2 | | 6 | TABLE ACCESS FULL | SOUTH | 1 | 2 | ---------------------------------------------------------------- 353
  • 354. NORTH 4WD SMART CARS SOUTH 4WD SMART CARS 354
  • 356. SQL> select ... 2 from NORTH n, SOUTH s 3 where n.model = s.model ------------------------------------------------------------- | Id | Operation | Name | Rows | Pstart| Pstop | ------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1003K| | | | 1 | PARTITION RANGE ALL| | 1003K| 1 | 2 | |* 2 | HASH JOIN | | 1003K| | | | 3 | TABLE ACCESS FULL| NORTH | 1000K| 1 | 2 | | 4 | TABLE ACCESS FULL| SOUTH | 1000K| 1 | 2 | ------------------------------------------------------------- 356
  • 358. SQL> select /*+ PARALLEL(n) PARALLEL(s) */ ... 2 from north n, south s 3 where n.model = s.model ---------------------------------------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | TQ |IN-OUT| PQ Distrib | ---------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | | | | 1 | PX COORDINATOR | | | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | | | Q1,01 | P->S | QC (RAND) | |* 3 | HASH JOIN | | | | Q1,01 | PCWP | | | 4 | PX BLOCK ITERATOR | | 1 | 2 | Q1,01 | PCWC | | | 5 | TABLE ACCESS FULL | NORTH | 1 | 2 | Q1,01 | PCWP | | | 6 | BUFFER SORT | | | | Q1,01 | PCWC | | | 7 | PX RECEIVE | | | | Q1,01 | PCWP | | | 8 | PX SEND BROADCAST LOCAL| :TQ10000 | | | Q1,00 | P->P | BCST LOCAL | | 9 | PX BLOCK ITERATOR | | 1 | 2 | Q1,00 | PCWC | | | 10 | TABLE ACCESS FULL | SOUTH | 1 | 2 | Q1,00 | PCWP | | ---------------------------------------------------------------------------------------------- 358
  • 359. Slave 1 Slave 2 NORTH 4WD SMART CARS SOUTH 4WD SMART CARS Slave 3 Slave 4 359
  • 360. partitions must match exactly 360
  • 361. if not, better in 11g 361
  • 362. fallback to bloom filter 362
  • 363. SQL> select ... 2 from NORTH n, SOUTH s 3 where n.model = s.model ---------------------------------------------------------------- | Id | Operation | Name | Pstart| Pstop | ---------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | |* 1 | HASH JOIN | | | | | 2 | PART JOIN FILTER CREATE | :BF0000 | | | | 3 | PARTITION RANGE ALL | | 1 | 2 | | 4 | TABLE ACCESS FULL | NORTH | 1 | 2 | | 5 | PARTITION RANGE JOIN-FILTER| |:BF0000|:BF0000| | 6 | TABLE ACCESS FULL | SOUTH |:BF0000|:BF0000| ---------------------------------------------------------------- 363
  • 364. if nececssary, brew your own don't assume 364
  • 365. 365
  • 366. wrap up 366
  • 367. all positive 367
  • 369. pitfalls # 1 369
  • 370. SQL> select * from v$option; PARAMETER VALUE -------------------------------------------------- -------- Partitioning TRUE Objects TRUE Real Application Clusters TRUE Advanced replication TRUE Bit-mapped indexes TRUE Connection multiplexing TRUE Connection pooling TRUE Database queuing TRUE Incremental backup and recovery TRUE Instead-of triggers TRUE Parallel backup and recovery TRUE Parallel execution TRUE Parallel load TRUE 370
  • 371.
  • 372. even in EE 372
  • 374. pitfalls # 2 374
  • 375. boundary cases constraint validation 375
  • 376. boundary cases statistics gathering 376
  • 377. boundary cases shared pool 377
  • 378. boundary cases reference partitions 378
  • 379. test with sql trace 379
  • 380. Connor McDonald OracleDBA co.uk 380
  • 381. ORA-00041 “active time limit exceeded - session terminated” www.oracledba.co.uk 381