Job Seekers   Employers
dbapool: Authors | Submissions | Contact Us
   Forgot password? | Sign up
  Home   Discussion Forum   Articles   Interview Questions   FAQs   Scripts   Rewards   Analyzer   White Papers   Blog   Certification   Downloads   Tools
   
Table Partition Performance analysis




By Vinod Sadanandan
Jan 07, 2008

Digg! digg!     Print    email to friend Email to Friend

Note: This article was written for educational purpose only. Please refer to the related vendor documentation for detail.




Download Free Confio Software

Table Partition Performance analysis

Collection of Statistics for Cost-Based Optimization/DBMS_STATS vs. ANALYZE

The cost-based approach relies on statistics and if the cost-based Approach is used , then statistics should be generated for all tables, clusters, and all types of indexes accessed by your SQL statements. If the size and data distribution of your tables change frequently, then generate statistics regularly to ensure the statistics accurately represent the data in the tables.

SELECT * FROM TEST PARTITION;

This uses global statistics but no predicate

SELECT * FROM TEST S WHERE S.AMOUNT_OF_SHIFT > 1000;

This uses a predicate for more than one partition and may use global statistics

SELECT * FROM TEST PARTITION (SEP2009) S WHERE S.AMOUNT_OF_SHIFT > 1000;

This uses global statistics and predicate to one partition.

Gathering global statistics with the DBMS_STATS package is more useful because ANALYZE always runs serially. DBMS_STATS can run in serial or parallel. Whenever possible, DBMS_STATS calls a parallel query to gather statistics with the specified degree of parallelism; otherwise, it calls a serial query or the ANALYZE statement. Index statistics are not gathered in parallel.

ANALYZE gathers statistics for the individual partitions and then calculates the global statistics from the partition statistics. DBMS_STATS can gather separate statistics for each partition as well as global statistics for the entire table or index. Depending on the SQL statement being optimized, the optimizer may choose to use either the partition (or subpartition) statistics or the global statistics.


CREATE TABLE PARTTAB(
ordid NUMBER,
PARTCOL DATE,
DETAILS NUMBER,
AMOUNT NUMBER)
PARTITION BY RANGE(PARTCOL)
SUBPARTITION BY HASH(DETAILS) SUBPARTITIONS 2
(PARTITION q1 VALUES LESS THAN(TO_DATE('01-04-2009','DD-MM-YYYY')) TABLESPACE TBLSPCE1,
PARTITION q2 VALUES LESS THAN(TO_DATE('01-07-2009','DD-MM-YYYY')) TABLESPACE TBLSPCE2,
PARTITION q3 VALUES LESS THAN(TO_DATE('01-10-2009','DD-MM-YYYY')) TABLESPACE TBLSPCE3,
PARTITION q4 VALUES LESS THAN(TO_DATE('01-12-2009','DD-MM-YYYY')) TABLESPACE TBLSPCE4
);

A local non prefixed index will be associated with it:

CREATE INDEX IDX_PARTTAB ON PARTTAB (ordid) LOCAL;

The PARTTAB table has been populated before to start the following examples.


GATHER_TABLE_STATS

Collects table, column, and index statistics.

Compute, serial mode, without histograms, Default granularity.

SQL> execute dbms_stats.gather_table_stats(-
>ownname => 'test',-
>tabname => 'PARTTAB',-
>partname => null,- --> Gather stats on all partitions.
>estimate_percent => null,- --> Compute mode
>block_sample => false,- --> Default value. No Sense in Compute mode
>method_opt => 'FOR ALL COLUMNS SIZE 1',- --> Table and columns statistics. No histogram generated
>degree => null,- --> default parallel degree based on DOP set on PARTTAB.
>granularity => 'default',- --> Gather Global and Partition statistics
>cascade => true ,- --> with index stats generated
>stattab => null,- --> The statistics will be stored in the dictionary.
>statid => null,-
>statown => null);

PL/SQL procedure successfully completed.


Index Statistics won't be calculated by default if CASCADE=>TRUE .


SQL> select table_name, NUM_ROWS, BLOCKS, EMPTY_BLOCKS, AVG_SPACE, AVG_ROW_LEN
, GLOBAL_STATS, USER_STATS, sample_size from user_tables
where table_name = 'PARTTAB';

TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE AVG_ROW_LEN GLOBAL_STATS USER_STATS SAMPLE_SIZE
---------- -------- ------ ------------ --------- ----------- ------------ ---------- -----------
PARTTAB 400 8 0 0 11 YES NO 400

Now that the statistics have been updated.
The column GLOBAL_STATS has been also initialized.

SQL> select partition_name "Partition", NUM_ROWS, BLOCKS, EMPTY_BLOCKS, AVG_SPACE, AVG_ROW_LEN,
SAMPLE_SIZE, global_stats, user_stats
from user_tab_partitions
where table_name = 'PARTTAB'
order by partition_position
/

Partition NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE AVG_ROW_LEN GLOBAL_STATS USER_STATS SAMPLE_SIZE
---------- -------- ------ ------------ ---------- ----------- ------------ ---------- -----------
Q1 100 2 0 0 11 YES NO 100
Q2 100 2 0 0 11 YES NO 100
Q3 100 2 0 0 11 YES NO 100
Q4 100 2 0 0 11 YES NO 100


The statistics are again obtained at the table level with the GLOBAL_STATS .

SQL> select partition_name \"Partition\", subpartition_name \"Subpartition\", NUM_ROWS, BLOCKS, EMPTY_BLOCKS
SAMPLE_SIZE, global_stats, user_stats
from user_tab_subpartitions
where table_name = 'PARTTAB'
order by partition_name, subpartition_position
/

Partition Subpartition NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE AVG_ROW_LEN SAMPLE_SIZE GLOBAL_STATS USER_STATS
---------- ------------- -------- ------ ------------ --------- ----------- ----------- ------------ ----------
Q1 SYS_SUBP10365 NO NO
Q1 SYS_SUBP10366 NO NO
Q2 SYS_SUBP10367 NO NO
Q2 SYS_SUBP10368 NO NO
Q3 SYS_SUBP10369 NO NO
Q3 SYS_SUBP10370 NO NO
Q4 SYS_SUBP10371 NO NO
Q4 SYS_SUBP10372 NO NO

The statistics aren't computed at the subpartition level which is in phase
with the 'DEFAULT' granularity.


SQL>select COLUMN_NAME, NUM_DISTINCT, DENSITY, NUM_NULLS, NUM_BUCKETS, LAST_ANALYZED from
user_tab_col_statistics where table_name = 'PARTTAB'
/

COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS NUM_BUCKETS LAST_ANALYZED
--------------- ------------ ---------- ---------- ----------- -------------
ORDID 0 0 400 1 12-DEC-02
PARTCOL 4 .25 0 1 12-DEC-02
DETAILS 100 .01 0 1 12-DEC-02
AMOUNT 0 0 400 1 12-DEC-02

The NUM_BUCKETS is set to 1 as there is no histogram generation. but, the column
statistics are well initialized

The same result is showed below on each partition columns:

SQL>select partition_name, COLUMN_NAME, NUM_DISTINCT, DENSITY, NUM_NULLS, NUM_BUCKETS, LAST_ANALYZED from user_part_col_statistics
where table_name = 'PARTTAB'
/

PARTITION_ COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS NUM_BUCKETS LAST_ANALYZED
---------- --------------- ------------ ---------- ---------- ----------- -------------
Q1 ORDID 0 0 100 1 12-DEC-07
Q1 PARTCOL 1 1 0 1 12-DEC-07
Q1 DETAILS 100 .01 0 1 12-DEC-07
Q1 AMOUNT 0 0 100 1 12-DEC-07
Q2 ORDID 0 0 100 1 12-DEC-07
Q2 PARTCOL 1 1 0 1 12-DEC-07
Q2 DETAILS 100 .01 0 1 12-DEC-07
Q2 AMOUNT 0 0 100 1 12-DEC-07
Q3 ORDID 0 0 100 1 12-DEC-07
Q3 PARTCOL 1 1 0 1 12-DEC-07
Q3 DETAILS 100 .01 0 1 12-DEC-07
Q3 AMOUNT 0 0 100 1 12-DEC-07
Q4 ORDID 0 0 100 1 12-DEC-07
Q4 PARTCOL 1 1 0 1 12-DEC-07
Q4 DETAILS 100 .01 0 1 12-DEC-07
Q4 AMOUNT 0 0 100 1 12-DEC-07


the statistics loaded for subpartitions of the PARTTAB table are displayed below:

SQL> select subpartition_name \"Subpartition\", COLUMN_NAME, NUM_DISTINCT, DENSITY, NUM_NULLS,
NUM_BUCKETS from dba_subpart_col_statistics where table_name = 'PARTTAB'
order by column_name
/

Subpartition COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS NUM_BUCKETS
--------------- --------------- ------------ ---------- ---------- -----------
SYS_SUBP10365 PARTCOL
SYS_SUBP10365 ORDID
SYS_SUBP10365 DETAILS
SYS_SUBP10365 AMOUNT
SYS_SUBP10366 PARTCOL
SYS_SUBP10366 ORDID
SYS_SUBP10366 DETAILS
SYS_SUBP10366 AMOUNT
SYS_SUBP10367 PARTCOL
SYS_SUBP10367 ORDID
SYS_SUBP10367 DETAILS
SYS_SUBP10367 AMOUNT
SYS_SUBP10368 PARTCOL
SYS_SUBP10368 ORDID
SYS_SUBP10368 DETAILS
SYS_SUBP10368 AMOUNT
SYS_SUBP10369 PARTCOL
SYS_SUBP10369 ORDID
SYS_SUBP10369 DETAILS
SYS_SUBP10369 AMOUNT
SYS_SUBP10370 PARTCOL
SYS_SUBP10370 ORDID
SYS_SUBP10370 DETAILS
SYS_SUBP10370 AMOUNT
SYS_SUBP10371 PARTCOL
SYS_SUBP10371 ORDID
SYS_SUBP10371 DETAILS
SYS_SUBP10371 AMOUNT
SYS_SUBP10372 PARTCOL
SYS_SUBP10372 ORDID
SYS_SUBP10372 DETAILS
SYS_SUBP10372 AMOUNT

No statistics were loaded on subpartition's columns.

Here partitioned objects contain more than one sets of statistics. This is because statistics can be generated for the entire object, partition, or subpartition.
 

 

 
About author:

Sr.Oracle DBA(UNIX) 7+ yrs experience in Database Administration ,Unix shell scripting ,PL/SQL,T-SQL - Migrations\version upgrade\one off patches on mission critical databases with high availability across Asia Pacific ,Europe and U.S for world's largest financial giants. - High end performance tuning for >10TB's DB in RAC/VCS/Dataguard,Standby / UNIX env - Designed automation scripts for database upgrade\CPU Patching,monitoring,audit in RAC /VCS , -Secondary skills Sybase 12.0/12.5,MSSQL 7,2000

 

Please login to post your comments





  About Us Advertise Terms of Use Privacy Newsletters Contact Us    

Home   Discussion Forum   FAQs  Articles  Jobs   Newsletters  Directory  Downloads 

Our Premium Sponsor
Confio Software