SQL优化案例-正确的使用索引(二)

本文探讨了如何通过改进SQL查询语句和合理使用索引来提高数据库查询效率。通过具体案例分析,展示了如何针对含有LIKE谓词的查询进行优化,减少回表次数,并最终实现查询速度的显著提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面sql 30秒执行出结果,查看sql谓词中有like,我们知道谓词中有这样的语句是不走索引的(为了保护客户的隐私,表名和部分列已经重命名)。

SELECT /*+1*/
CHECKNUM AS PINGZBSM,
CHECKDATE,
XXXMODE,
XXXRESULT,
(SELECT RESULT 
FROM (select ID,to_char(WMSYS.WM_CONCAT(xxxnum||xxxtype||xxxmode||xxxresult)) RESULT 
       from OOOO_XXXCHECKLOG 
      WHERE CHECKDATE BETWEEN DATE'2018-05-04' AND DATE'2018-05-04' and xxxtype like '%PAR'
      GROUP BY ID
    ) b where b.id=a.id
) RESULT,
CLERKNUM AS CHECKNUM
FROM OOO_XXXECHECKLOG A;

逻辑读600多万。查看索引情况如下


表过滤返回数据量如下:

SQL> select count(*) from OOOO_XXXCHECKLOG;
2799616
select count(*) from OOOO_XXXCHECKLOG WHERE CHECKDATE BETWEEN DATE'2018-05-04' AND DATE'2018-05-04' and xxxtype like '%PAR';
 12856
select count(*) from OOOO_XXXCHECKLOG WHERE CHECKDATE BETWEEN DATE'2018-05-04' AND DATE'2018-05-04';
197984

通过查询上面返回数据可知,因为xxxtype不走索引,所以通过索引要回表197984次,如果走了索引只回表12856次。

下面我们建立REVERSE索引IDX_ID_TYPE_RE

SELECT /*+OOOO_XXXCHECKLOG index(IDX_ID_TYPE_RE) 2*/
CHECKNUM AS PINGZBSM,
CHECKDATE,
XXXMODE,
XXXRESULT,
(SELECT RESULT 
FROM (select ID,to_char(WMSYS.WM_CONCAT(xxxnum||xxxtype||xxxmode||xxxresult)) RESULT 
       from OOOO_XXXCHECKLOG 
      WHERE CHECKDATE BETWEEN DATE'2018-05-04' AND DATE'2018-05-04' and REVERSE(xxxtype) like 'RAP%'
      GROUP BY ID
    ) b where b.id=a.id
) RESULT,
CLERKNUM AS CHECKNUM
FROM OOO_XXXECHECKLOG A;

查看执行计划如下,逻辑读将为300万,但是时间还是维持在18秒,根本原因在于这个索引因为标量子查询的问题被访问700万次导致。


下面我们改写sql如下

SELECT /*+ index(OOOO_XXXCHECKLOG IDX_ID_TYPE_RE) 3*/
CHECKNUM AS PINGZBSM,
CHECKDATE,
XXXMODE,
XXXRESULT,
B.RESULT,
CLERKNUM AS CHECKNUM
FROM OOO_XXXECHECKLOG A
left join (select ID,to_char(WMSYS.WM_CONCAT(xxxnum||xxxtype||xxxmode||xxxresult)) RESULT 
       from OOOO_XXXCHECKLOG 
      WHERE CHECKDATE BETWEEN DATE'2018-05-04' AND DATE'2018-05-04' and REVERSE(xxxtype) like 'RAP%'
      GROUP BY ID
    ) b on b.id=a.id;

执行计划中出现index_skip_scan。 

下面我们创建如下索引:

create index idx_date_seal_re on OOOO_XXXCHECKLOG(CHECKDATE,REVERSE(xxxtype));

可以看到,逻辑读降到64424,50个物理读是因为刚刚创建索引的原因,sql也秒出。


|  作者简介

姚崇·沃趣科技高级数据库技术专家

熟悉Oracle数据库内部机制,丰富的数据库及RAC集群层故障诊断、性能调优、OWI、数据库备份恢复及迁移经验。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值