oracle 一条简单sql的优化

教程发布:风哥 教程分类:ITPUX技术网 更新日期:2022-02-12 浏览学习:1162

[p=25, null, left][color=rgb(62, 62, 62)]sql_id:5s1wx1pppquax:[p=25, null, left][color=rgb(62, 62, 62)][p=25, null, left][color=rgb(62, 62, 62)]select count(1) count from t_vou_XXXX voucher[p=25, null, left][color=rgb(62, 62, 62)] where batch_no = :1 and customer_no is not null;
执行计划:[p=25, null, left][color=rgb(62, 62, 62)][img]http://mmbiz.qpic.cn/mmbiz/VkC3lgPs6ca0GFgACUGQARxGkrDE083ib4OkW83nZPAdEP8YNI1dBLJAetwNoupvg2CUYWZY6AsRO1g8sBMMaUg/0?wx_fmt=jpeg[/img]
[p=25, null, left][color=rgb(62, 62, 62)]执行信息:
[img=689,42]http://mmbiz.qpic.cn/mmbiz/VkC3lgPs6ca0GFgACUGQARxGkrDE083ib3aibrcxoXOlpKT4tuvkcB4icNFzSmK9mfL9PaumK4IibV9q2HBREZEpnQ/0?wx_fmt=jpeg[/img]

[p=25, null, left][color=rgb(62, 62, 62)]表信息:[p=25, null, left][color=rgb(62, 62, 62)]SQL> select NUM_ROWS from dba_tables where table_name='T_VOU_XXXX';[p=25, null, left][color=rgb(62, 62, 62)] NUM_ROWS[p=25, null, left][color=rgb(62, 62, 62)] ----------[p=25, null, left][color=rgb(62, 62, 62)] 184266247[p=25, null, left][color=rgb(62, 62, 62)]大小 42.4G[p=25, null, left][color=rgb(62, 62, 62)]索引信息:[p=25, null, left][color=rgb(62, 62, 62)]batch_no,customer_no列上 各自有单独的索引
[p=25, null, left][color=rgb(62, 62, 62)]列统计信息:[p=25, null, left][color=rgb(62, 62, 62)][img=518,91]http://mmbiz.qpic.cn/mmbiz/VkC3lgPs6ca0GFgACUGQARxGkrDE083ibFM33YqVa70FCuWQjib5TQ5yacoTWzmCHGBicnr69KnHibnB14Qpq6Sz6g/0?wx_fmt=jpeg[/img]
[p=25, null, left][color=rgb(62, 62, 62)]执行计划分析:[p=25, null, left][color=rgb(62, 62, 62)]该sql 首先走的是batch_no列上的索引(id=3),然后再通过rowid回表(id=2),再聚合(id=1)[p=25, null, left][color=rgb(62, 62, 62)]从上面的信息我们可以发现 此sql使用730693288的执行计划,平均单次执行需要333s,执行效率较差。[p=25, null, left][color=rgb(62, 62, 62)][p=25, null, left][color=rgb(62, 62, 62)][p=25, null, left][color=rgb(62, 62, 62)]优化思路:[p=25, null, left][color=rgb(62, 62, 62)]从执行计划的步骤和sql内容上,我们可以发现该sql 是统计满足这2个条件的数据量,并且执行计划中有回表的操作,[p=25, null, left][color=rgb(62, 62, 62)]至此我们就有了优化的思路,建立组合索引,避免执行计划中的回表操作。[p=25, null, left][color=rgb(62, 62, 62)]怎么建组合索引?[p=25, null, left][color=rgb(62, 62, 62)]该表这2个列都有独自的索引。因此需要改造下。 列的统计信息如上, 通常我们建组合索引,选择性好的放在前面(可以避免index skip scan),因此按照常规的我们的索引列顺序为 ('CUSTOMER_NO','BATCH_NO'),但是如果这样建索引,对于我们的这个sql优化,没有用。从sql的where条件可以发现,若是走这个索引,则是(index full scan),因此这样是行不通的。故我们建索引的顺序为('BATCH_NO','CUSTOMER_NO'),并且删掉原来的batch_no上的冗余索引,因CUSTOMER_NO有单独的索引,因此index skip scan的情景就不必担心会发生。[p=25, null, left][color=rgb(62, 62, 62)]
[p=25, null, left][color=rgb(62, 62, 62)]实施步骤:[p=25, null, left][color=rgb(62, 62, 62)][p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]1、--估算索引大小:[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]4.6G 现有空间12G, 估算建完后还剩余7G 使用率(85-7)/85*100%=91.7%,会触发告警因此需要加空间[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]set serverout on[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]variable used_bytes number[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]variable alloc_bytes number[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]exec dbms_space.create_index_cost('create index i_vou_info_batch_cust_no on t_vou_XXXX( batch_no ,customer_no ) tablespace TBS_VOUCHER_IDX local online parallel 16',:used_bytes,:alloc_bytes);[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]print :used_bytes[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]print :alloc_bytes[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit][p=25, null, left][color=rgb(62, 62, 62)]2、建立索引:
[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]create index i_vou_info_batch_cust_no on t_vou_XXXX( batch_no ,customer_no ) tablespace TBS_VOUCHER_IDX local online parallel 8;[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]alter index i_vou_info_batch_cust_no noparallel;[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]3、invisible原有的索引:[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]alter index I_VOU_INFO_BATCH_NO invisible;[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]4、观察是否使用新建的索引,及前后的性能变化:[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit][img]http://mmbiz.qpic.cn/mmbiz/VkC3lgPs6ca0GFgACUGQARxGkrDE083ibSFXJ1VDmclibrVNyTlZ9ibFvgAaNCTA9qyZ85IYicCl2dhFVqRDerFFwg/0?wx_fmt=jpeg[/img]
Peeked Binds (identified by position):[p=25, null, left][color=rgb(62, 62, 62)]--------------------------------------[p=25, null, left][color=rgb(62, 62, 62)] 1 - :1 (VARCHAR2(30), CSID=871): 'B20160512112812105'[p=25, null, left][color=rgb(62, 62, 62)]Predicate Information (identified by operation id):[p=25, null, left][color=rgb(62, 62, 62)]---------------------------------------------------[p=25, null, left][color=rgb(62, 62, 62)] 3 - access("BATCH_NO"=:1)[p=25, null, left][color=rgb(62, 62, 62)] filter("CUSTOMER_NO" IS NOT NULL)
[img=700,0]http://mmbiz.qpic.cn/mmbiz/VkC3lgPs6ca0GFgACUGQARxGkrDE083iby04IQWvKnMqZqiaGaPdDPaAWHwYL2FA7d8kV8CRlKv3Wzq932GHgj8w/0?wx_fmt=jpeg[/img]
[p=25, null, left][color=rgb(62, 62, 62)]优化后的sql,执行时间由原来的平均每次332s,到优化有的平均每次不超过2s,优化后的sql执行性能有明显的提高。[p=25, null, left][color=rgb(62, 62, 62)][backcolor=inherit]5、删除原有的索引:[p=25, null, left][color=rgb(62, 62, 62)]drop index I_VOU_INFO_BATCH_NO;

本文标签:
网站声明:本文由风哥整理发布,转载请保留此段声明,本站所有内容将不对其使用后果做任何承诺,请读者谨慎使用!
【上一篇】
【下一篇】