Professional Documents
Culture Documents
Star Schema
Reasons of Partitioning
avoid unnecessary index and table scans improve the performance of massive join operations dramatically reduces the time required for administrative tasks (es backup, restore ..) Partitioning also allows one to swap partitions with a table
swapping can be used to keep a large amount of data that is being loaded inaccessible until loading is completed, or can be used as a way to stage data between different phases of use
Partitioning Methods
Range Partitioning Hash Partitioning List Partitioning Composite Partitioning
Range Partition
CREATE TABLE sales_range (salesman_id NUMBER(5), salesman_name VARCHAR2(30), sales_amount NUMBER(10), sales_date DATE) PARTITION BY RANGE(sales_date) (PARTITION sales_jan2000 VALUES LESS THAN(TO_DATE('02/01/2000','DD/MM/YYYY')), PARTITION sales_feb2000 VALUES LESS THAN(TO_DATE('03/01/2000','DD/MM/YYYY')), PARTITION sales_mar2000 VALUES LESS THAN(TO_DATE('04/01/2000','DD/MM/YYYY')), PARTITION sales_apr2000 VALUES LESS THAN(TO_DATE('05/01/2000','DD/MM/YYYY')));
List Partitioning
CREATE TABLE sales_list ( salesman_id NUMBER(5), salesman_name VARCHAR2(30), sales_state VARCHAR2(20), sales_amount NUMBER(10), sales_date DATE ) PARTITION BY LIST(sales_state) (PARTITION sales_west VALUES('California', 'Hawaii'), PARTITION sales_east VALUES ('New York', 'Virginia', 'Florida'), PARTITION sales_central VALUES('Texas', 'Illinois'), PARTITION sales_other VALUES(DEFAULT));
Hash Partitioning
CREATE TABLE sales_hash (salesman_id NUMBER(5), salesman_name VARCHAR2(30), sales_amount NUMBER(10), week_no NUMBER(2)) PARTITION BY HASH(salesman_id) PARTITIONS 4;
Composite Partitioning
Range-Hash Range-List Oracle Database first distributes data by range then further divide the data into subpartitions within each range partition, by list or by hash.
Range-Hash Partitioning
CREATE TABLE sales_range_hash( s_productid NUMBER, s_saledate DATE, s_custid NUMBER, s_totalprice NUMBER) PARTITION BY RANGE (s_saledate) SUBPARTITION BY HASH (s_productid) SUBPARTITIONS 8 (PARTITION sal99q1 VALUES LESS THAN (TO_DATE('01-APR-1999', 'DD-MON-YYYY')), PARTITION sal99q2 VALUES LESS THAN (TO_DATE('01-JUL-1999', 'DD-MON-YYYY')), PARTITION sal99q3 VALUES LESS THAN (TO_DATE('01-OCT-1999', 'DD-MON-YYYY')), PARTITION sal99q4 VALUES LESS THAN (TO_DATE('01-JAN-2000', 'DD-MON-YYYY'))); CREATE TABLE sales_range_hash( s_productid NUMBER, s_saledate DATE, s_custid NUMBER, s_totalprice NUMBER) PARTITION BY RANGE (s_saledate) SUBPARTITION BY HASH (s_productid) SUBPARTITION TEMPLATE( SUBPARTITION sp1 TABLESPACE tbs1,SUBPARTITION sp2 TABLESPACE tbs2,SUBPARTITION sp3 TABLESPACE tbs3,SUBPARTITION sp4 TABLESPACE tbs4,SUBPARTITION sp5 TABLESPACE tbs5,SUBPARTITION sp6 TABLESPACE tbs6,SUBPARTITION sp7 TABLESPACE tbs7,SUBPARTITION sp8 TABLESPACE tbs8) (PARTITION sal99q1 VALUES LESS THAN (TO_DATE('01-APR-1999', 'DD-MON-YYYY')), PARTITION sal99q2 VALUES LESS THAN (TO_DATE('01-JUL-1999', 'DD-MON-YYYY')), PARTITION sal99q3 VALUES LESS THAN (TO_DATE('01-OCT-1999', 'DD-MON-YYYY')), PARTITION sal99q4 VALUES LESS THAN (TO_DATE('01-JAN-2000', 'DD-MON-YYYY')));
Range-List Partitioning
CREATE TABLE quarterly_regional_sales (deptno NUMBER, item_no VARCHAR2(20), txn_date DATE, txn_amount NUMBER, state VARCHAR2(2)) PARTITION BY RANGE (txn_date) SUBPARTITION BY LIST (state) ( PARTITION q1_1999 VALUES LESS THAN(TO_DATE('1-APR-1999','DD-MON-YYYY')) (SUBPARTITION q1_1999_northwest VALUES ('OR', 'WA'), SUBPARTITION q1_1999_southwest VALUES ('AZ', 'UT', 'NM'), SUBPARTITION q1_1999_northeast VALUES ('NY', 'VM', 'NJ'), SUBPARTITION q1_1999_southeast VALUES ('FL', 'GA'), SUBPARTITION q1_1999_northcentral VALUES ('SD', 'WI'), SUBPARTITION q1_1999_southcentral VALUES ('NM', 'TX')), PARTITION q2_1999 VALUES LESS THAN(TO_DATE('1-JUL-1999','DD-MON-YYYY')) (SUBPARTITION q2_1999_northwest VALUES ('OR', 'WA'), SUBPARTITION q2_1999_southwest VALUES ('AZ', 'UT', 'NM'), SUBPARTITION q2_1999_northeast VALUES ('NY', 'VM', 'NJ'), SUBPARTITION q2_1999_southeast VALUES ('FL', 'GA'), SUBPARTITION q2_1999_northcentral VALUES ('SD', 'WI'), SUBPARTITION q2_1999_southcentral VALUES ('NM', 'TX')), PARTITION q3_1999 VALUES LESS THAN (TO_DATE('1-OCT-1999','DD-MON-YYYY')) (SUBPARTITION q3_1999_northwest VALUES ('OR', 'WA'), SUBPARTITION q3_1999_southwest VALUES ('AZ', 'UT', 'NM'), SUBPARTITION q3_1999_northeast VALUES ('NY', 'VM', 'NJ'), SUBPARTITION q3_1999_southeast VALUES ('FL', 'GA'), SUBPARTITION q3_1999_northcentral VALUES ('SD', 'WI'), SUBPARTITION q3_1999_southcentral VALUES ('NM', 'TX')), PARTITION q4_1999 VALUES LESS THAN (TO_DATE('1-JAN-2000','DD-MON-YYYY')) (SUBPARTITION q4_1999_northwest VALUES('OR', 'WA'), SUBPARTITION q4_1999_southwest VALUES('AZ', 'UT', 'NM'), SUBPARTITION q4_1999_northeast VALUES('NY', 'VM', 'NJ'), SUBPARTITION q4_1999_southeast VALUES('FL', 'GA'), SUBPARTITION q4_1999_northcentral VALUES ('SD', 'WI'), SUBPARTITION q4_1999_southcentral VALUES ('NM', 'TX')));
CREATE TABLE quarterly_regional_sales (deptno NUMBER, item_no VARCHAR2(20), txn_date DATE, txn_amount NUMBER, state VARCHAR2(2)) PARTITION BY RANGE (txn_date) SUBPARTITION BY LIST (state) SUBPARTITION TEMPLATE( SUBPARTITION northwest VALUES ('OR', 'WA') TABLESPACE ts1, SUBPARTITION southwest VALUES ('AZ', 'UT', 'NM') TABLESPACE ts2, SUBPARTITION northeast VALUES ('NY', 'VM', 'NJ') TABLESPACE ts3, SUBPARTITION southeast VALUES ('FL', 'GA') TABLESPACE ts4, SUBPARTITION northcentral VALUES ('SD', 'WI') TABLESPACE ts5, SUBPARTITION southcentral VALUES ('NM', 'TX') TABLESPACE ts6) ( PARTITION q1_1999 VALUES LESS THAN(TO_DATE('1-APR-1999','DD-MON-YYYY')), PARTITION q2_1999 VALUES LESS THAN(TO_DATE('1-JUL-1999','DD-MON-YYYY')), PARTITION q3_1999 VALUES LESS THAN(TO_DATE('1-OCT-1999','DD-MON-YYYY')), PARTITION q4_1999 VALUES LESS THAN(TO_DATE('1-JAN-2000','DD-MON-YYYY')));
Partition Pruning
Oracle Database prunes partitions when: you use range, LIKE, equality, and IN-list predicates on the range or list partitioning columns you use equality and IN-list predicates on the hash partitioning columns
Range Pruning
select prod_id,country_id,cust_gender, sum(quantity_sold) quantity_sold ,sum(amount_sold) amount_sold from sh.sales s, sh.customers c where s.cust_id=c.cust_id and s.time_id between '01/01/1999' and '01/12/1999' group by s.prod_id,c.country_id, cust_gender
SELECT c.cust_last_name, COUNT(*) FROM sales_hash s, customers_hash c WHERE s.cust_id = c.cust_id AND s.time_id BETWEEN TO_DATE('01-JUL-1999', 'DD-MON-YYYY') AND (TO_DATE('01-OCT-1999', 'DD-MON-YYYY')) GROUP BY c.cust_last_name HAVING COUNT(*) > 100;
The customers and sales tables are both partitioned by hash into 16 partitions, on the s_customerid and c_customerid columns.
If in RAC, You must ensure that all these partitions are placed on the same node as the matching hash partition from the other table
(Composite-Hash)-Hash
pruning is achieved by scanning only the hash subpartitions correspondingto Q3 of 1999 then joins these subpartitions with the hash one of customer table, using a full partition-wise join The degree of parallelism for this full partition-wise join cannot exceed 16. Even though the sales table has 128 subpartitions, it has only 16 hash partitions
The (Composite-List)-List is like (Composite-Hash)-Hash (Composite-Composite (Hash/List Dimension) is similar. There could be a pruning on Customer table too.
The execution involves two sets of query servers: one set, labeled set 1 in scans the customers table in parallel. Rows from customers that are selected by the first set, in this case all rows, are redistributed to the second set of query servers by hashing customerid The degree of parallelism does not need to equal the number of partitions
Index Partitioning
A Index can be partitioned. You can mix partitioned and non-partitioned indexes with partitioned and non-partitioned tables: 1) non-partitioned table can have 1a) partitioned 1b) non-partitioned B-tree indexes. 2) A partitioned table can have 2a) partitioned 2b) non-partitioned indexes.
SalesCustHPIdx -H3
SalesCustHPIdx -H4
cust4
cust6 cust8
cust2 cust10
Sales 2001 20
Cust1,Cust3,Cust4 Cust5,Cust6,Cust11
Sales 2002
Cust7,Cust8
Sales 2003
Cust2,Cust7,Cust10
Sales 2004
Cust1, Cust4,Cust9Cust10
SalesCustIdx -2001
SalesCustIdx -2002
SalesCustIdx -2003
SalesCustIdx -2004
cust1
cust6 cust9
cust2 cust10
Sales 20
SQL> create index sal_custid_hpidx on sales_btree_p(cust_id) global partition by hash (cust_id) partitions 32 ; Indice creato.
SalesCustIdx -2001
SalesCustIdx -2002
SalesCustIdx -2003
SalesCustIdx -2004
cust1
cust3
cust6 cust1
cust6 cust9
cust2
Sales 2001 20
Sales 2002
Sales 2003
Sales 2004
H1 20
H2
H3
H4
A local index is prefixed if it is partitioned on a left prefix of the index columns A local prefixed index can be unique index
cust1
cust3
cust6 cust1
cust6 cust9
cust2
Sales 2001 20
Sales 2002
Sales 2003
Sales 2004
Nonprefixed indexes are particularly useful in historical databases. You might create a nonprefixed local index SalesCustIdx on sales. The SalesCustIdx index is defined on cust_id, because there are queries that need fast access to the data by cust_id. However, it is partitioned on time_id to match the sales table. Every year, the oldest partitions of sales and SalesCustIdx are dropped and new ones are added. You cannot have a unique local nonprefixed index unless the partitioning key is a subset , even if it s not a index prefix, of the index key. (ex: Index Key=Cust_id,Time_id)
Local Prefixed (any partitioning method) Local nonprefixed (any partitioning method) Global Prefixed (range and hash partitioning only)
Yes No Yes
A A A
A,B B,A B
A A B
For a unique local nonprefixed index, the partitioning key must be a subset of the index key. **Although a global partitioned index may be equipartitioned with the underlying table, Oracle does not take advantage of the partitioning or maintain equipartitioning after partition maintenance operations such as DROP or SPLIT PARTITION.
H1 20
H2
H3
H4
SalesCustIdx -2001
SalesCustIdx -2002
SalesCustIdx -2003
cust1
cust3
cust6 cust1
cust6 cust9
cust2
Sales 2001 20
Sales 2002
Sales 2003
Sales 2004
Bitmap indexes on non partitioned tables cannot be partitioned. A bitmap index on a partitioned table must be a local index. There is nothing to prevent a global index from being equipartitioned with the underlying table but Oracle does not take advantage of the equipartitioning when generating query plans or executing partition maintenance operations. So an index that is equipartitioned with the underlying table should be created as LOCAL.