设为首页 收藏本站
查看: 395|回复: 0

[经验分享] 聊聊Oracle 11g中的Reference Partition(下)

[复制链接]

尚未签到

发表于 2015-12-16 15:02:55 | 显示全部楼层 |阅读模式
 
上篇中,我们介绍了Reference Partition的创建、使用和原理。本篇将从性能和管理两个角度,讨论Reference Partition的作用。
 
4Reference Partition与执行计划
 
直观上看,Reference Partition应当是有益于执行计划的。主子表之间通过外键进行关联,最常用的业务场景就是借助外键列进行关联查询。如果主表记录是在一个或者几个分区上,那么子表对应的记录应该是在一个或者几个分区上。
这样,就从定义层面减少了数据访问量。下面通过一系列的实验进行证明。
 
 
SQL> explain plan for select * from t_master a, t_detail b where a.object_id=b.master_id;
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2684484261
--------------------------------------------------------------------------------
|>  | Operation            | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| T
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |   238K|    18M|       |   642   (3)| 0
|   1 |  PARTITION LIST ALL  |          |   238K|    18M|       |   642   (3)| 0
|   2 |   MERGE JOIN         |          |   238K|    18M|       |   642   (3)| 0
|   3 |    SORT JOIN         |          |   120K|  4936K|    12M|   222   (3)| 0
|   4 |     TABLE ACCESS FULL| T_MASTER |   120K|  4936K|       |   217   (1)| 0
|*  5 |    SORT JOIN         |          |   240K|  9403K|    23M|   419   (3)| 0
|   6 |     TABLE ACCESS FULL| T_DETAIL |   240K|  9403K|       |   412   (1)| 0
--------------------------------------------------------------------------------
Predicate Information (identified by operation>
---------------------------------------------------
   5 - access("A"."OBJECT_ID"="B"."MASTER_ID")
       filter("A"."OBJECT_ID"="B"."MASTER_ID")
 
19 rows selected
 
 
第一个语句我们没有加入分区条件,访问了所有的分区,路径中出现了“Partition List All”语句。注意:分区表的全表扫描,成本要大于扫描一张大表。分区表最大意义在于加入分区条件的查询语句。
第二个语句,我们加入主表的owner分区条件。
 
 
SQL> explain plan for select * from t_master a, t_detail b where a.object_id=b.master_id and owner='SCOTT';
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3648887064
--------------------------------------------------------------------------------
|>  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time

--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |  2600 |   198K|   495   (1)| 00:00:06
|   1 |  PARTITION LIST SINGLE|          |  2600 |   198K|   495   (1)| 00:00:06
|*  2 |   HASH JOIN           |          |  2600 |   198K|   495   (1)| 00:00:06
|*  3 |    TABLE ACCESS FULL  | T_MASTER |  1312 | 49856 |    82   (0)| 00:00:01
|   4 |    TABLE ACCESS FULL  | T_DETAIL |   240K|  9403K|   412   (1)| 00:00:05
--------------------------------------------------------------------------------
Predicate Information (identified by operation>
---------------------------------------------------
   2 - access("A"."OBJECT_ID"="B"."MASTER_ID")
   3 - filter("OWNER"='SCOTT')
 
17 rows selected
 
 
注意:该语句中,利用owner条件,扫描的重点集中在t_master的单一分区,进行了“Partition List Single”操作,扫描之后的结果,在子表中“一定对应”一个子表分区。所以对T_Detail的扫描也是Partition List Single
如果子表没有分区,我们进行一下实验。
 
 
SQL> create table t_normal as select * from t_detail;
Table created
 
SQL> commit;
Commit complete
 
SQL> exec dbms_stats.gather_table_stats(user,'T_NORMAL',cascade => true);
PL/SQL procedure successfully completed
 
 
查看执行计划:
 
 
SQL> explain plan for select * from t_master a, t_normal b where a.object_id=b.master_id and owner='SCOTT';
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1706510341
--------------------------------------------------------------------------------
|>  | Operation              | Name     | Rows  | Bytes | Cost (%CPU)| Time

--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |  2600 |   198K|   494   (1)| 00:00:0
|*  1 |  HASH JOIN             |          |  2600 |   198K|   494   (1)| 00:00:0
|   2 |   PARTITION LIST SINGLE|          |  1312 | 49856 |    82   (0)| 00:00:0
|*  3 |    TABLE ACCESS FULL   | T_MASTER |  1312 | 49856 |    82   (0)| 00:00:0
|   4 |   TABLE ACCESS FULL    | T_NORMAL |   240K|  9403K|   411   (1)| 00:00:0
--------------------------------------------------------------------------------
Predicate Information (identified by operation>
---------------------------------------------------
   1 - access("A"."OBJECT_ID"="B"."MASTER_ID")
   3 - filter("OWNER"='SCOTT')
 
17 rows selected
 
 
请注意对T_NORMAL表的“Table Access Full”操作,它并没有涉及到分区。也就是说,从t_master中筛选到的记录owner=SCOTT’到T_NORMAL中,进行的是全表扫描操作。
从现在执行计划,我们的确看到了Reference Partition在执行计划上的优势。那么,还有无提升空间?
余地就是外键索引!为了避免大规模并发过程中出现死锁的情况,外键列是要求加索引的。笔者如果在Reference Partition的情况下,加入索引,会如何呢?
 
 
SQL> create index> local;
Index created
 
SQL> exec dbms_stats.gather_table_stats(user,'T_DETAIL',cascade => true);
PL/SQL procedure successfully completed
 
 
执行计划:
 
 
SQL> explain plan for select * from t_master a, t_detail b where a.object_id=b.master_id and owner='SCOTT';
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
---------------------------------------
Plan hash value: 3648887064
------------------------------------------------
|>  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time

-----------------------------------------------------------
|   0 | SELECT STATEMENT      |          |  2600 |   198K|   495   (1)| 00:00:06
|   1 |  PARTITION LIST SINGLE|          |  2600 |   198K|   495   (1)| 00:00:06
|*  2 |   HASH JOIN           |          |  2600 |   198K|   495   (1)| 00:00:06
|*  3 |    TABLE ACCESS FULL  | T_MASTER |  1312 | 49856 |    82   (0)| 00:00:01
|   4 |    TABLE ACCESS FULL  | T_DETAIL |   240K|  9403K|   412   (1)| 00:00:05
--------------------------------------------------------
Predicate Information (identified by operation>
---------------------------------------------------
   2 - access("A"."OBJECT_ID"="B"."MASTER_ID")
   3 - filter("OWNER"='SCOTT')
 
17 rows selected
 
 
执行计划没有改变,说明在CBO计算过程中,索引策略被分区策略成本值“打败”了。这个在很多没有特殊调优的分区表语句中十分常见。
笔者尝试了一下直方图路径,看是否可以生成更好的执行计划。
 
 
SQL> exec dbms_stats.gather_table_stats(user,'T_MASTER',cascade => true,method_opt => 'for all columns>);
 
PL/SQL procedure successfully completed
 
SQL> exec dbms_stats.gather_table_stats(user,'T_DETAIL',cascade => true,method_opt => 'for all columns>);
 
PL/SQL procedure successfully completed
 
 
执行计划情况:
 
 
SQL> explain plan for select * from t_master a, t_detail b where a.object_id=b.master_id and owner='SCOTT';
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------
Plan hash value: 2296204501
------------------------------------------------------------------------------------------------------------------------
|>  | Operation                           | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |

------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                  |    35 |  2730 |   136   (0)| 00:00:02 |       |       |
|   1 |  PARTITION LIST SINGLE              |                  |    35 |  2730 |   136   (0)| 00:00:02 |   KEY |   KEY |
|   2 |   NESTED LOOPS                      |                  |    35 |  2730 |   136   (0)| 00:00:02 |       |       |
|   3 |    NESTED LOOPS                     |                  |    36 |  2730 |   136   (0)| 00:00:02 |       |       |
|*  4 |     TABLE ACCESS FULL               | T_MASTER         |    18 |   684 |    82   (0)| 00:00:01 |     3 |     3 |
|*  5 |     INDEX RANGE SCAN                |>     2 |       |     1   (0)| 00:00:01 |   KEY |   KEY |

|   6 |    TABLE ACCESS BY LOCAL INDEX ROWID| T_DETAIL         |     2 |    80 |     3   (0)| 00:00:01 |   KEY |   KEY |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation>
---------------------------------------------------
   4 - filter("OWNER"='SCOTT')
   5 - access("A"."OBJECT_ID"="B"."MASTER_ID")
 
19 rows selected
 
 
索引路径走到,执行计划成本下降到136
说明:在使用Reference Partition的情况下,主子表外键连接的语句的确可以得到一定程度的性能提升。更容易生成更好的执行计划。
 
5、管理角度
 
从管理角度看,Reference Partition将主子表记录“牢牢”的绑定在一起,对应的分区也紧密关系在一起。
如果我们对主表分区进行操作处理,对应的子表分区也会进行自动的操作。下面我们操作t_master对象分区。
我们将主表分区p1摘除,仅从主从表记录关系看,数据库应该让先删除子表记录。
 
 
SQL>>
Table>
 
 
摘除成功,说明Reference Partition连带影响子表分区被删除。
 
 
SQL> col num_rows for a10;
SQL> col high_value for a10;
SQL> col partition_name for a10;
SQL> col table_name for a10;
SQL> select table_name, partition_name, high_value,num_rows from dba_tab_partitions where table_owner='SYS' and table_name in
 
('T_DETAIL','T_MASTER');
 
TABLE_NAME PARTITION_ HIGH_VALUE   NUM_ROWS
---------- ---------- ---------- ----------
T_DETAIL   P0                         67992
T_DETAIL   P3                         97096
T_MASTER   P0         'PUBLIC'        33996
T_MASTER   P3         default         48548
 
 
主子表分区联动处理。
 
6、结论
 
Reference PartitionOracle 11g推出的一个重要的新特性。借助该特性,我们从定义分区表、管理分区表和使用分区表等多个方面,都可以得到很多好处。

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-152117-1-1.html 上篇帖子: 使用OPatch给Oracle打补丁 下篇帖子: 通过oracle触发器记录修改某表的用户和ip地址
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表