暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

利用rowid分块实现分区表的并行执行时的一个注意点

当我们查询、更新、删除几百GB的非分区大表或已分区但单分区过大时,为了解决01555等问题,经常需要通过ROWID切片的方式,并行执行,减少单次执行时间。当我们切分分区表的一个分区后,查询时除了rowid between ‘xxxx’ and 'xxxx’外还需要显示指定分区名,否则将会扫描ALL PARTITIONS。
演示如下

SQL> @seg TEST.TEST_PART_TAB

    SEG_MB OWNER   SEGMENT_NAME                   SEG_PART_NAME                  SEGMENT_TYPE         SEG_TABLESPACE_NAME                BLOCKS     HDRFIL     HDRBLK
---------- ------- ------------------------------ ------------------------------ -------------------- ------------------------------ ---------- ---------- ----------
      3143 TEST     TEST_PART_TAB     P142407                        TABLE PARTITION      HS_DAT                             402304         95    2012305
      2240 TEST     TEST_PART_TAB     P143119                        TABLE PARTITION      HS_DAT                             286720         95    2013329
      3119 TEST     TEST_PART_TAB     P143989                        TABLE PARTITION      HS_DAT                             399232         95    2014353
      3133 TEST     TEST_PART_TAB     P144724                        TABLE PARTITION      HS_DAT                             401024         95    2015377
      3221 TEST     TEST_PART_TAB     P145449                        TABLE PARTITION      HS_DAT                             412288         95    2016401
      3498 TEST     TEST_PART_TAB     P147312                        TABLE PARTITION      HS_DAT                             447744         95    2018449
      6719 TEST     TEST_PART_TAB     P147736                        TABLE PARTITION      HS_DAT                             860032         95    2019473
      7552 TEST     TEST_PART_TAB     P148165                        TABLE PARTITION      HS_DAT                             966656         95    2020497
     10944 TEST     TEST_PART_TAB     P148889                        TABLE PARTITION      HS_DAT                            1400832         95    2021521
      3063 TEST     TEST_PART_TAB     P150498                        TABLE PARTITION      HS_DAT                             392064         95    2023569
      2752 TEST     TEST_PART_TAB     P151284                        TABLE PARTITION      HS_DAT                             352256         95    2024593
      2752 TEST     TEST_PART_TAB     P152083                        TABLE PARTITION      HS_DAT                             352256         95    2025617
      3008 TEST     TEST_PART_TAB     P152840                        TABLE PARTITION      HS_DAT                             385024         95    2026641
      3004 TEST     TEST_PART_TAB     P153613                        TABLE PARTITION      HS_DAT                             384512         95    2027665
      2944 TEST     TEST_PART_TAB     P155869                        TABLE PARTITION      HS_DAT                             376832         95    2029713
      3008 TEST     TEST_PART_TAB     P156594                        TABLE PARTITION      HS_DAT                             385024         95    2030737
      3008 TEST     TEST_PART_TAB     P157318                        TABLE PARTITION      HS_DAT                             385024         95    2031761
      3135 TEST     TEST_PART_TAB     P159139                        TABLE PARTITION      HS_DAT                             401280         95    2032785
      2254 TEST     TEST_PART_TAB     P162234                        TABLE PARTITION      HS_DAT                             288512         95    2034833
      2021 TEST     TEST_PART_TAB     P165489                        TABLE PARTITION      HS_DAT                             258688         95    2035857
      2240 TEST     TEST_PART_TAB     P168295                        TABLE PARTITION      HS_DAT                             286720         95    2036881
      3300 TEST     TEST_PART_TAB     P146340                        TABLE PARTITION      HS_DAT                             422400         95    2017425
     11562 TEST     TEST_PART_TAB     P149657                        TABLE PARTITION      HS_DAT                            1479936         95    2022545
      2944 TEST     TEST_PART_TAB     P155029                        TABLE PARTITION      HS_DAT                             376832         95    2028689
      2503 TEST     TEST_PART_TAB     P160489                        TABLE PARTITION      HS_DAT                             320384         95    2033809
      2304 TEST     TEST_PART_TAB     P168991                        TABLE PARTITION      HS_DAT                             294912         95    2037905
      8768 TEST     TEST_PART_TAB     P173380                        TABLE PARTITION      HS_DAT                            1122304         95    2038929

27 rows selected.

SQL> @partition_table_trunk_by_rowid
Enter value for trunks: 6
Enter value for owner: TEST
Enter value for table_name: TEST_PART_TAB
Enter value for part_name: P149657

ROWID2
--------------------------------------------------------------------
 where  rowid between 'AADxxCAARAAC3aAAAA' and 'AADxxCABlAADML/CcP';
 where  rowid between 'AADxxCABlAADOMAAAA' and 'AADxxCAB/AAC75/CcP';
 where  rowid between 'AADxxCAB/AADCsAAAA' and 'AADxxCACMAAC+L/CcP';
 where  rowid between 'AADxxCACMAADEMAAAA' and 'AADxxCACaAADB7/CcP';
 where  rowid between 'AADxxCACaAADKMAAAA' and 'AADxxCACnAADML/CcP';
 where  rowid between 'AADxxCACnAADSMAAAA' and 'AADxxCAC+AADJr/CcP';

6 rows selected.



explain plan for
select count(*) from TEST.TEST_PART_TAB where rowid between ‘AADxxCAARAAC3aAAAA’ and ‘AADxxCABlAADML/CcP’;
image.png

explain plan for
select count(*) from TEST.TEST_PART_TAB partition(P149657) where rowid between ‘AADxxCAARAAC3aAAAA’ and ‘AADxxCABlAADML/CcP’;
image.png

角本partition_table_trunk_by_rowid.sql

select  /*+ rule */ ' where  rowid between '''||dbms_rowid.rowid_create(1, oid1, fid1, bid1, 0) ||''' and '''||
       dbms_rowid.rowid_create(1, oid2, fid2, bid2, 9999) || ''';' rowid2
  from (select a.*, rownum rn  
          from (select chunk_no,  
                       min(oid1) oid1,  
                       max(oid2) oid2,  
                       min(fid1) fid1,  
                       max(fid2) fid2,  
                       min(bid1) bid1,  
                       max(bid2) bid2  
                  from (select chunk_no,  
                               FIRST_VALUE(data_object_id) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) oid1,  
                               LAST_VALUE(data_object_id) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) oid2,  
                               FIRST_VALUE(relative_fno) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) fid1,  
                               LAST_VALUE(relative_fno) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) fid2,  
                               FIRST_VALUE(block_id) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) bid1,  
                               LAST_VALUE(block_id + blocks - 1) OVER(PARTITION BY chunk_no ORDER BY data_object_id, relative_fno, block_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) bid2  
                          from (select data_object_id,  
                                       relative_fno,  
                                       block_id,  
                                       blocks,  
                                       ceil(sum2 / chunk_size) chunk_no  
                                  from (select  b.data_object_id,  
                                               a.relative_fno,  
                                               a.block_id,  
                                               a.blocks,  
                                               sum(a.blocks) over(order by b.data_object_id, a.relative_fno, a.block_id) sum2,  
                                               ceil(sum(a.blocks)  
                                                    over() / &trunks) chunk_size  
                                          from dba_extents a, dba_objects b  
                                         where a.owner = b.owner  
                                           and a.segment_name = b.object_name  
                                           and nvl(a.partition_name, '-1') =  
                                               nvl(b.subobject_name, '-1')  
                                           and b.data_object_id is not null  
                                           and a.owner = upper('&owner')  
                                           and a.segment_name = upper('&table_name')
										   and a.PARTITION_NAME=upper('&part_name')
										   )))  
                 group by chunk_no  
                 order by chunk_no) a); 
最后修改时间:2020-09-18 10:12:16
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论