10.6 Partition Pruning

   

Even when you don't name a specific partition in a SQL statement, the fact that a table is partitioned might still influence the manner in which the statement accesses the table. When a SQL statement accesses one or more partitioned tables, the Oracle optimizer attempts to use the information in the WHERE clause to eliminate some of the partitions from consideration during statement execution. This process, called partition pruning, speeds statement execution by ignoring any partitions that cannot satisfy the statement's WHERE clause. To do so, the optimizer uses information from the table definition combined with information from the statement's WHERE clause. For example, given the following table definition:

CREATE TABLE tab1 (   col1 NUMBER(5) NOT NULL,   col2 DATE NOT NULL,   col3 VARCHAR2(10) NOT NULL) PARTITION BY RANGE (col2)  (PARTITION tab1_1998      VALUES LESS THAN (TO_DATE('01-JAN-1999','DD-MON-YYYY'))       TABLESPACE t1,   PARTITION tab1_1999      VALUES LESS THAN (TO_DATE('01-JAN-2000','DD-MON-YYYY'))       TABLESPACE t1,   PARTITION tab1_2000      VALUES LESS THAN (TO_DATE('01-JAN-2001','DD-MON-YYYY'))       TABLESPACE t3,   PARTITION tab1_2001      VALUES LESS THAN (TO_DATE('01-JAN-2002','DD-MON-YYYY'))       TABLESPACE t4);

and the following query:

SELECT col1, col2, col3 FROM tab1 WHERE col2 > TO_DATE('01-OCT-2000','DD-MON-YYYY');

the optimizer would eliminate partitions tab1_1998 and tab1_1999 from consideration, since neither partition could contain rows with a value for col2 greater than October 1, 2000.

Partition pruning is sometimes referred to as partition elimination.


For the optimizer to make these types of decisions, the WHERE clause must reference at least one column from the set of columns that comprise the partition key. Although this might seem fairly straightforward, not all queries against a partitioned table naturally include the partition key. If a unique index exists on the col1 column of the tab1 table from the previous example, for instance, the following query would generally offer the most efficient access:

SELECT col1, col2, col3 FROM tab1 WHERE col1 = 1578;

If the index on col1 had been defined as a local index, however, Oracle would need to visit each partition's local index to find the one that holds the value 1578. If you also have information about the partition key (col2 in this case), you might want to consider including it in the query so that the optimizer can eliminate partitions, as in the following:

SELECT col1, col2, col3 FROM tab1 WHERE col1 = 1578    AND col2 > TO_DATE('01-JAN-2001','DD-MON-YYYY');

With the additional condition, the optimizer can now eliminate the tab1_1998, tab1_1999, and tab1_2000 partitions from consideration. Oracle will now search a single unique index on the tab1_2001 partition instead of searching a unique index on each of the four table partitions. Of course, you would need to know that data pertaining to the value 1578 also had a value for col2 greater then January 1, 2001. If you can reliably provide additional information regarding the partition keys, than you should do so; otherwise, you'll just have to let the optimizer do its best. Running EXPLAIN PLAN on your DML statements against partitioned tables will allow you to see which partitions the optimizer decided to utilize.

When checking the results of EXPLAIN PLAN, there are a couple of partition specific columns that you should add to your query against plan_table to see which partitions are being considered by the optimizer. To demonstrate, we'll explain the following query against tab1:

EXPLAIN PLAN  SET STATEMENT_ID = 'qry1' FOR SELECT col1, col2, col3 FROM tab1 WHERE col2 BETWEEN TO_DATE('01-JUL-1999','DD-MON-YYYY')   AND TO_DATE('01-JUL-2000','DD-MON-YYYY');

When querying the plan_table table, you should include the partition_start and partition_end columns whenever the operation field starts with 'PARTITION':

SELECT lpad(' ',2 * level) || operation || ' ' ||   options || ' ' || object_name ||    DECODE(SUBSTR(operation, 1, 9), 'PARTITION',     ' FROM ' || partition_start ||      ' TO ' || partition_stop, ' ') "exec plan" FROM plan_table CONNECT BY PRIOR id = parent_id START WITH id = 0 AND statement_id = 'qry1'; exec plan ------------------------------------------------------   SELECT STATEMENT     PARTITION RANGE ITERATOR  FROM 2 TO 3       TABLE ACCESS FULL TAB1

The value of PARTITION RANGE for the operation column along with the value of ITERATOR for the options column indicates that more than one partition will be involved in the execution plan.[2] The values of the partition_start and partition_end columns (2 and 3, respectively) indicate that the optimizer has decided to prune partitions 1 and 4, which correlate to the tab1_1998 and tab1_2001 partitions.[3] Given that the WHERE clause specifies a date range of July 1, 1999 to July 1, 2000, the optimizer has correctly pruned all partitions that cannot contribute to the result set.

[2] If the optimizer had pruned all but one partition, the options column would contain the value 'SINGLE'. If no partitions were pruned, the options column would contain the value 'ALL'.

[3] The number shown in the partition_start and partition_end columns correlates to the partition_position column in the user_tab_partitions table, so you can query this table to identify the names of the partitions that are included in the execution plan.



Mastering Oracle SQL
Mastering Oracle SQL, 2nd Edition
ISBN: 0596006322
EAN: 2147483647
Year: 2003
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net