打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Partition-Wise Join of List-Partitioned Tables

Partition-Wise Join of List-Partitioned Tables

When two tables are equi-partitioned on their join keys, the query optimizer is able to take advantage of partition-wise joins. To make sure that the tables are equi-partitioned, as of Oracle Database 11g reference partitioning can be used. In fact, per definition, with reference partitioning all “related” tables have exactly the same partitioning schema. If you are not using reference partitioning, you must be very careful that the tables are effectively partitioned in very same way. For range and hash partitioned tables this is usually not a problem. However, when using list partitioning, it is quite easy to make a mistake. The reason is that the partitions can be defined in any order. Let’s have a look to an example based on the following two tables.

SQL> CREATE TABLE t1p  2  PARTITION BY LIST (pkey) (  3    PARTITION p_0 VALUES (0),  4    PARTITION p_1 VALUES (1),  5    PARTITION p_2 VALUES (2),  6    PARTITION p_3 VALUES (3),  7    PARTITION p_4 VALUES (4),  8    PARTITION p_5 VALUES (5),  9    PARTITION p_6 VALUES (6), 10    PARTITION p_7 VALUES (7), 11    PARTITION p_8 VALUES (8), 12    PARTITION p_9 VALUES (9) 13  ) 14  AS 15  SELECT rownum AS num, mod(rownum,10) AS pkey, dbms_random.string('p',50) AS pad 16  FROM dual 17  CONNECT BY level <= 10000;SQL> CREATE TABLE t2p  2  PARTITION BY LIST (pkey) (  3    PARTITION p_0 VALUES (0),  4    PARTITION p_1 VALUES (1),  5    PARTITION p_2 VALUES (2),  6    PARTITION p_3 VALUES (3),  7    PARTITION p_5 VALUES (5),  8    PARTITION p_4 VALUES (4),  9    PARTITION p_6 VALUES (6), 10    PARTITION p_7 VALUES (7), 11    PARTITION p_8 VALUES (8), 12    PARTITION p_9 VALUES (9) 13  ) 14  AS 15  SELECT rownum AS num, mod(rownum,10) AS pkey, dbms_random.string('p',50) AS pad 16  FROM dual 17  CONNECT BY level <= 10000;SQL> BEGIN  2    dbms_stats.gather_table_stats(user,'t1p');  3    dbms_stats.gather_table_stats(user,'t2p');  4  END;  5  /

Even though they are logically equivalent, as shown in the following execution plan, with them partition-wise joins cannot be used.

SQL> EXPLAIN PLAN FOR SELECT * FROM t1p JOIN t2p USING (num, pkey);SQL> SELECT * FROM table(dbms_xplan.display(format=>'basic'));PLAN_TABLE_OUTPUT------------------------------------Plan hash value: 3059592055------------------------------------| Id  | Operation           | Name |------------------------------------|   0 | SELECT STATEMENT    |      ||   1 |  HASH JOIN          |      ||   2 |   PARTITION LIST ALL|      ||   3 |    TABLE ACCESS FULL| T1P  ||   4 |   PARTITION LIST ALL|      ||   5 |    TABLE ACCESS FULL| T2P  |------------------------------------

The difference in the order of the partitions can also be confirmed by a query like the following one.

SQL> SELECT t1p.high_value,  2         t1p.partition_position AS pos_t1p,  3         t2p.partition_position AS pos_t2p,  4         decode(t1p.partition_position, t2p.partition_position, 'Y', 'N') AS equal  5  FROM user_tab_partitions t1p JOIN user_tab_partitions t2p ON t1p.partition_name = t2p.partition_name  6  WHERE t1p.table_name = 'T1P'  7  AND t2p.table_name = 'T2P';HIGH_VALUE   POS_T1P  POS_T2P EQUAL----------- -------- -------- ------0                  1        1 Y1                  2        2 Y2                  3        3 Y3                  4        4 Y5                  6        5 N4                  5        6 N6                  7        7 Y7                  8        8 Y8                  9        9 Y9                 10       10 Y

It goes without saying that to solve the problem it is necessary to reorder the partitions. To do so it is enough to move the out-of-order partitions. To avoid a double storage of the data a series of ALTER TABLE EXCHANGE/DROP/ADD/EXCHANGE statements can be used.

  • Move the P5 partition of the T1P table

SQL> CREATE TABLE t1p_5 AS  2  SELECT *  3  FROM t1p PARTITION (p_5)  4  WHERE 1 = 0;SQL> ALTER TABLE t1p EXCHANGE PARTITION p_5 WITH TABLE t1p_5;SQL> ALTER TABLE t1p DROP PARTITION p_5;SQL> ALTER TABLE t1p ADD PARTITION p_5 VALUES (5);SQL> ALTER TABLE t1p EXCHANGE PARTITION p_5 WITH TABLE t1p_5;SQL> DROP TABLE t1p_5 PURGE;

  • Move the P5 partition of the T2P table

SQL> CREATE TABLE t2p_5 AS  2  SELECT *  3  FROM t2p PARTITION (p_5)  4  WHERE 1 = 0;SQL> ALTER TABLE t2p EXCHANGE PARTITION p_5 WITH TABLE t2p_5;SQL> ALTER TABLE t2p DROP PARTITION p_5;SQL> ALTER TABLE t2p ADD PARTITION p_5 VALUES (5);SQL> ALTER TABLE t2p EXCHANGE PARTITION p_5 WITH TABLE t2p_5;SQL> DROP TABLE t2p_5 PURGE;

  • Check whether the order is ok

SQL> SELECT t1p.high_value,  2         t1p.partition_position AS pos_t1p,  3         t2p.partition_position AS pos_t2p,  4         decode(t1p.partition_position, t2p.partition_position, 'Y', 'N') AS equal  5  FROM user_tab_partitions t1p JOIN user_tab_partitions t2p ON t1p.partition_name = t2p.partition_name  6  WHERE t1p.table_name = 'T1P'  7  AND t2p.table_name = 'T2P';HIGH_VALUE   POS_T1P  POS_T2P EQUAL----------- -------- -------- ------0                  1        1 Y1                  2        2 Y2                  3        3 Y3                  4        4 Y4                  5        5 Y6                  6        6 Y7                  7        7 Y8                  8        8 Y9                  9        9 Y5                 10       10 Y

After these operations partition-wise joins are allowed. The following execution plan confirms this.

SQL> SELECT * FROM table(dbms_xplan.display(format=>'basic'));PLAN_TABLE_OUTPUT------------------------------------Plan hash value: 1324269388------------------------------------| Id  | Operation           | Name |------------------------------------|   0 | SELECT STATEMENT    |      ||   1 |  PARTITION LIST ALL |      ||   2 |   HASH JOIN         |      ||   3 |    TABLE ACCESS FULL| T1P  ||   4 |    TABLE ACCESS FULL| T2P  |------------------------------------

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Managing Optimizer statistics in an Oracle Database 11g
普通表->分区表
《Oracle DBA日常工作和职责》
如何使用SQLPLUS分析SQL语句
恢复历史统计信息
收集oracle统计信息
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服