112.mysql in导致的索引失效优化案例

1.原来的SQL;

# Query_time: 100.474167  Lock_time: 0.000165 Rows_sent: 167  Rows_examined: 3287596
SET timestamp=1706061618;
select * from b_vehicle_loss_component lcomp where lcomp.OperateStatus<>'D' 
and lcomp.id in ( select lkk.lossid from b_case_loss_coverage lkk 
 where lkk.lossapprovalid in ( 
   select l.lossapprovalid from b_vehicle_loss l 
   where 1=1 and l.verifyflag in ('1','3') 
   and l.veripflag in ('N','1','3') 
   and l.objectid in ( 
      select lc.objectid from b_case_object lc 
      where lc.reportno ='07318000002024000014' )) 
	  and lkk.kindcode not in('BZ') 
);

--查看执行计划:

explain select * from b_vehicle_loss_component lcomp where lcomp.OperateStatus<>'D' 
and lcomp.id in ( select lkk.lossid from b_case_loss_coverage lkk 
 where lkk.lossapprovalid in ( 
   select l.lossapprovalid from b_vehicle_loss l 
   where 1=1 and l.verifyflag in ('1','3') 
   and l.veripflag in ('N','1','3') 
   and l.objectid in ( 
      select lc.objectid from b_case_object lc 
      where lc.reportno ='07318000002024000014' )) 
	  and lkk.kindcode not in('BZ') 
);

+----+--------------+-------------+------------+------+--------------------------------------------------------+-------------------------------+---------+--------------------------+---------+----------+----------------------------------------------------+
| id | select_type  | table       | partitions | type | possible_keys                                          | key                           | key_len | ref                      | rows    | filtered | Extra                                              |
+----+--------------+-------------+------------+------+--------------------------------------------------------+-------------------------------+---------+--------------------------+---------+----------+----------------------------------------------------+
|  1 | SIMPLE       | <subquery2> | NULL       | ALL  | NULL                                                   | NULL                          | NULL    | NULL                     |    NULL |     0.00 | NULL                                               |
|  1 | SIMPLE       | lcomp       | NULL       | ALL  | PRIMARY,Id                                             | NULL                          | NULL    | NULL                     | 2094983 |     0.00 | Using where; Using join buffer (Block Nested Loop) |
|  2 | MATERIALIZED | lc          | NULL       | ref  | idx_lclaimlossitems_itemid,idx_lclmlositem_registno    | idx_lclmlositem_registno      | 69      | const                    |       2 |   100.00 | Using where                                        |
|  2 | MATERIALIZED | l           | NULL       | ref  | PRIMARY,idx_lcarlossapproval_itemid                    | idx_lcarlossapproval_itemid   | 93      | hxappdb.lc.ObjectId      |       1 |     6.00 | Using where                                        |
|  2 | MATERIALIZED | lkk         | NULL       | ref  | idx_llossapprovalkindcode_aid,idx_llosskindcode_lossid | idx_llossapprovalkindcode_aid | 123     | hxappdb.l.LossApprovalId |       3 |    90.00 | Using where                                        |
+----+--------------+-------------+------------+------+--------------------------------------------------------+-------------------------------+---------+--------------------------+---------+----------+----------------------------------------------------+
5 rows in set, 1 warning (0.01 sec)
lcomp 表未使用到索引,且该表上ID字段上有索引。优化目前是让其使用索引。

--2.优化。

--优化后lcomp 能使用到了索引
explain select lcomp.* from b_vehicle_loss_component lcomp 
JOIN 
( select distinct lkk.lossid from b_case_loss_coverage lkk 
 where lkk.lossapprovalid in ( 
   select  l.lossapprovalid from b_vehicle_loss l 
   where 1=1 and l.verifyflag in ('1','3') 
   and l.veripflag in ('N','1','3') 
   and l.objectid in ( 
      select lc.objectid from b_case_object lc 
      where lc.reportno ='07318000002024000014' )) 
	  and lkk.kindcode not in('BZ') 
) W ON  lcomp.id= W.lossid
where lcomp.OperateStatus<>'D' ;
+----+-------------+------------+------------+--------+--------------------------------------------------------+-------------------------------+---------+--------------------------+------+----------+-----------------------------------------------+
| id | select_type | table      | partitions | type   | possible_keys                                          | key                           | key_len | ref                      | rows | filtered | Extra                                         |
+----+-------------+------------+------------+--------+--------------------------------------------------------+-------------------------------+---------+--------------------------+------+----------+-----------------------------------------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL    | NULL                                                   | NULL                          | NULL    | NULL                     |    2 |   100.00 | Using where                                   |
|  1 | PRIMARY     | lcomp      | NULL       | eq_ref | PRIMARY,Id                                             | PRIMARY                       | 122     | W.lossid                 |    1 |    90.00 | Using where                                   |
|  2 | DERIVED     | lc         | NULL       | ref    | idx_lclaimlossitems_itemid,idx_lclmlositem_registno    | idx_lclmlositem_registno      | 69      | const                    |    2 |   100.00 | Using where; Using temporary; Start temporary |
|  2 | DERIVED     | l          | NULL       | ref    | PRIMARY,idx_lcarlossapproval_itemid                    | idx_lcarlossapproval_itemid   | 93      | hxappdb.lc.ObjectId      |    1 |     6.00 | Using where                                   |
|  2 | DERIVED     | lkk        | NULL       | ref    | idx_llossapprovalkindcode_aid,idx_llosskindcode_lossid | idx_llossapprovalkindcode_aid | 123     | hxappdb.l.LossApprovalId |    3 |    90.00 | Using where; End temporary                    |
+----+-------------+------------+------------+--------+--------------------------------------------------------+-------------------------------+---------+--------------------------+------+----------+-----------------------------------------------+
5 rows in set, 1 warning (0.01 sec)

--优化后执行时间0s;

select lcomp.* from b_vehicle_loss_component lcomp 
JOIN 
( select distinct lkk.lossid from b_case_loss_coverage lkk 
 where lkk.lossapprovalid in ( 
   select  l.lossapprovalid from b_vehicle_loss l 
   where 1=1 and l.verifyflag in ('1','3') 
   and l.veripflag in ('N','1','3') 
   and l.objectid in ( 
      select lc.objectid from b_case_object lc 
      where lc.reportno ='07318000002024000014' )) 
	  and lkk.kindcode not in('BZ') 
) W ON  lcomp.id= W.lossid
where lcomp.OperateStatus<>'D' ;

167 rows in set (0.00 sec)

3.对比

原来执行时间:100.474167s,IN 导致未使用到索引。
现在执行时间:0.00s ,IN 改为JOIN 后使用到了索引。
嵌套循环连接:Using join buffer (Block Nested Loop),在当前SQL中性能差,目前应该是索引范围扫描。

4.优化建议 

今天9:00~16点,有2000多条慢SQL,大多数都是和表:b_vehicle_loss_component相关。
WHERE 条件中使用了 IN 导致表没有使用到索引,执行时间:20s~100s的都有。
建议将IN 等价改写为 JOIN,这样可以使用到索引。
我抽样检查了一部分慢SQL,看到的全部是这个表的 IN 操作,SQL语句雷同。
如上为优化样例,建议按如上方法修改。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值