当前位置:  数据库>oracle

Oracle delete语句调优一例

    来源: 互联网  发布时间:2017-06-15

    本文导语: 今天刚上上班,就接到客户的邮件,说生产环境中执行某一条delete sql语句的时间超过了3个小时。最后客户无奈取消了这次数据清理,准备今天在申请时间重做。所以希望我在下午之前能够调优一下sql语句。 我拿到sql语句。是一...

今天刚上上班,就接到客户的邮件,说生产环境中执行某一条delete sql语句的时间超过了3个小时。最后客户无奈取消了这次数据清理,准备今天在申请时间重做。所以希望我在下午之前能够调优一下sql语句。

我拿到sql语句。是一个简单的delete语句,这个表是一个分区表,表中的数据大约有6亿条,要删除的数据大概有900多万条。

delete event
          where cycle_code = 25
          and cycle_month = 2
          and cycle_year = 2015
          and customer_id = 5289835;
先来看看执行计划
Plan hash value: 2439880320
 -----------------------------------------------------------------------------------------------------------------------
 | Id  | Operation                          | Name            | Rows  | Bytes | Cost (%CPU)| Time    | Pstart| Pstop |
 -----------------------------------------------------------------------------------------------------------------------
 |  0 | DELETE STATEMENT                    |                |  3238K|  135M|  404K  (1)| 01:20:52 |      |      |
 |  1 |  DELETE                            |      EVENT    |      |      |            |          |      |      |
 |  2 |  PARTITION RANGE ITERATOR          |                |  3238K|  135M|  404K  (1)| 01:20:52 |  241 |  261 |
 |*  3 |    TABLE ACCESS BY LOCAL INDEX ROWID|      EVENT    |  3238K|  135M|  404K  (1)| 01:20:52 |  241 |  261 |
 |*  4 |    INDEX RANGE SCAN                |      EVENT_1UQ |  1370K|      | 40255  (1)| 00:08:04 |  241 |  261 |
 -----------------------------------------------------------------------------------------------------------------------
发现走了索引扫描,看起来性能也不会差到哪去啊?
 从整体来看,从6亿条记录中删除900多万条数据,走索引扫描感觉感觉确实是不错的选择。

 首先查看了表的分区规则和基本的数据分布情况,
 分区规则是基于cycle_code,cycle_month,sub_partition_id这三个字段,从查询条件来看,cycle_code,cycle_month刚好就是分区字段。
TABLE_NAME          PARTITION PARTITION_COUNT COLUMN_LIST                    PART_COUNTS SUBPAR_COUNT STATUS
 -------------------- --------- --------------- ------------------------------ ----------- ------------ ------
 EVENT              RANGE                721 CYCLE_CODE,CYCLE_MONTH,SUB_PAR TITION_ID          3            0 VALID                                             
数据分布的情况如下,根据分区逻辑,数据只可能在这20个分区中。
partition_name  high_value  tablespace_name      num_rows
 C25_M2_S1    25, 2, 5        DATAH01              84246910
 C25_M2_S2    25, 2, 10      DATAH01              3427570
 C25_M2_S3    25, 2, 15      DATAH01              3523431
 C25_M2_S4    25, 2, 20      DATAH01              3988140
 C25_M2_S5    25, 2, 25      DATAH01              2700687
 C25_M2_S6    25, 2, 30      DATAH01              2477792
 C25_M2_S7    25, 2, 35      DATAH01              2490349
C25_M2_S8    25, 2, 40      DATAH01              11755212
 C25_M2_S9    25, 2, 45      DATAH01              3184953
 C25_M2_S10  25, 2, 50      DATAH01              2656802
 C25_M2_S11  25, 2, 55      DATAH01              4434668
 C25_M2_S12  25, 2, 60      DATAH01              2776079
 C25_M2_S13  25, 2, 65      DATAH01              2949885
 C25_M2_S14  25, 2, 70      DATAH01              2837790
 C25_M2_S15  25, 2, 75      DATAH01              6285172
 C25_M2_S16  25, 2, 80      DATAH01              2743439
 C25_M2_S17  25, 2, 85      DATAH01              3574228
 C25_M2_S18  25, 2, 90      DATAH01              3600820
 C25_M2_S19  25, 2, 95      DATAH01              7415434
 C25_M2_S20  25, 2, 100      DATAH01              3446285

有了这些信息,发现收获还是不小的,我写了一个脚本,来嵌入customer_id这个字段,来查看每个分区中需要删除的数据情况,结果发现第一个分区有8千多万条数据,查询的时间很长,最后竟然没有数据可以删除,其它的分区测试的时候执行速度都很快。
 分区C25_M2_S8中的要删除的数据有9百多万,其它分区都没有匹配的数据,从数据层面,我是没法确定这些分区一定没有可能插入新数据的。
 所以分析了上面的情况,我对分区C25_M2_S1做了特殊处理,按照执行计划是走索引扫描的,因为查询条件的范围有点大,还没有匹配的数据,所以我尝试走全表扫描,开启了并行,经过测试,发现速度还是很快的,基本在1分钟左右就能够很快过滤出数据来。
 所以从数据层面我提供的语句如下,把最大的分区放在了最后处理。
set linesize 200
 set timing on
 set time on
 alter session force parallel dml parallel 16;
 delete event partition(C25_M2_S2)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;
 delete event partition(C25_M2_S3)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;
 delete event partition(C25_M2_S4)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;
。。。。。。。
delete event partition(C25_M2_S20)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;
 delete /*+ full(rated_event) parallel(rated_event,16) */ event partition(C25_M2_S1)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;


事情到此一般就结束了,开发找到我,我们做了进一步的沟通,她根据我提供的脚本提出了一些问题,她从业务层面来做了确认,说数据只会在C25_M2_S8这个分区上,有了业务确认,调优的语句就更加简化了。
set linesize 200
set timing on
set time on
alter session force parallel dml parallel 16;
 delete event partition(C25_M2_S8)  where cycle_code=25 and cycle_month=2 and cycle_year=2015 and customer_id=5289835;
 commit;

查看执行计划,合理的走了全表扫描,因为分区中有1千多万的记录,删除900多万的数据,走全表扫描还是情理之中的。
Plan hash value: 1742190108
 ----------------------------------------------------------------------------------------------------------------------------------
 | Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time    | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
 ----------------------------------------------------------------------------------------------------------------------------------
 |  0 | DELETE STATEMENT      |            |  9115K|  382M| 19351  (1)| 00:03:53 |      |      |        |      |            |
 |  1 |  PX COORDINATOR      |            |      |      |            |          |      |      |        |      |            |
 |  2 |  PX SEND QC (RANDOM) | :TQ10000    |  9115K|  382M| 19351  (1)| 00:03:53 |      |      |  Q1,00 | P->S | QC (RAND)  |
 |  3 |    DELETE            |      EVENT |      |      |            |          |      |      |  Q1,00 | PCWP |            |
 |  4 |    PX BLOCK ITERATOR |            |  9115K|  382M| 19351  (1)| 00:03:53 |  248 |  248 |  Q1,00 | PCWC |            |
 |*  5 |      TABLE ACCESS FULL|      EVENT |  9115K|  382M| 19351  (1)| 00:03:53 |  248 |  248 |  Q1,00 | PCWP |            |
 ----------------------------------------------------------------------------------------------------------------------------------

通过这个例子,我们可以看到原本索引扫描的执行计划看起来很好,但是执行效率却大打折扣,在分析了分区表的分区规则和数据分布情况之后,发现可以把原本700多个分区简化到20个,加上业务层面的确认,本来20个分区的删除可以简化到有一个特定的分区,性能调优在这个时候就是一个接力棒式的工作。问题经过一步一步的分析和确认,也变得清晰起来。


    
 
 

您可能感兴趣的文章:

  • oracle导出sql语句的结果集和保存执行的sql语句(深入分析)
  • oracle用什么SQL语句判断表存不存在
  • 请问怎么用jsp语句删除oracle中的一条记录?
  • Oracle中SQL语句连接字符串的符号使用介绍
  • Oracle用什么语句查询字段?
  • 怎么在java中向一个sql语句传参数,就像oracle的proc一样啊?
  • 请问在 Linux 下如何用代码实现连接oracle数据库 并 执行 SQL 语句?
  • Oracle 9i轻松取得建表和索引的DDL语句
  • Oracle的SQL语句中如何处理‘&’符号
  • 关于Oracle中的sql语句的疑问,向大家请教。
  • Oracle Sql语句长度限制问题及解决
  • Oracle9i取得建表和索引的DDL语句
  • Oracle 中文字段进行排序的sql语句
  • oracle数据库添加或删除一列的sql语句
  • Oracle中查询本月星期5的所有日期列表的语句
  • Oracle中备份表的简单sql命令语句
  • oracle中误删除表后恢复语句(FLASHBACK)
  • Oracle判断指定列是否全部为数字的sql语句
  • jsp中在oracle中查询日期类型时sql语句该怎么写啊?
  • Oracle 常用的SQL语句
  • sqlserver中delete、update中使用表别名和oracle的区别
  • Oracle批量update和delete
  • ORACLE SQL-UPDATE、DELETE、INSERT优化和使用技巧分享
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Oracle 12c发布简单介绍及官方下载地址
  • 在linux下安装oracle,如何设置让oracle自动启动!也就是让oracle那个服务自动启动,不是手动的
  • oracle 11g最新版官方下载地址
  • 请问su oracle 和su - oracle有什么不同?
  • Oracle 数据库(oracle Database)Select 多表关联查询方式
  • 虚拟机装Oracle R12与Oracle10g
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • Oracle 数据库开发工具 Oracle SQL Developer
  • 如何设置让Oracle SQL Developer显示的时间包含时分秒
  • Oracle EBS R12 支持 Oracle Database 11g
  • Oracle 10g和Oracle 11g网格技术介绍
  • SCO unix下安装oracle,但没有光盘,请大家推荐一个oracle下载站点(unix版本的)。谢谢!!!!
  • oracle中如何把表中具有相同值列的多行数据合并成一行
  • 请问大家用oracle数据库, 用import oracle.*;下的东西么? 还是用标准库?
  • Oracle 数据库(oracle Database)性能调优技术详解
  • Linux /$ORACLE_HOME $ORACLE_HOME
  • ORACLE日期相关操作
  • Linux系统下Oracle的启动与Oracle监听的启动
  • ORACLE数据库常用字段数据类型介绍
  • 请问在solaris下安装ORACLE,用root用户和用oracle用户安装有什么区别么?
  • Oracle 12c的九大最新技术特性介绍
  • 网间Oracle的连接,远程连接Oracle服务器??


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3