线上有个查询sql,原来是inner join 查询没有问题,后来应业务要求改成left join之后, 查询时间就暴涨了 需要长达24s

在这里插入图片描述

通过explain分析,发现订单表没有走索引 ,分析之后解决了,记录下来。

为了简洁起见,这里就将无关的查询字段都用*

具体sql如下

SELECT  * 

 from t_item_detail a

 left join t_order_detail d on a.order_code=d.order_code

 left join t_connection b on a.unique_code = b.funds_unique 

 left join t_capital_detail c on b.capital_unique = c.unique_code 

 where item_receipt_disbursement=1 and a.is_deleted=0

  and order_type_code=00901 group by a.unique_code LIMIT 10 

用explain命令分析如下

在这里插入图片描述

发现table d 的type为all, rows居然高达20万行 。

d对应的表为order_detail 表,type为all 说明并没有走索引。

这里首先看关联条件

from t_item_detail a

 left join t_order_detail d on a.order_code=d.order_code

该条件并无问题,然后这两张表的order_code字段是否加索引.

在这里插入图片描述

在这里插入图片描述

d的索引就生效了,所有的索引都生效了。
查询时间也从原来的24秒 变成了不到1秒。

在这里插入图片描述

这是为什么呢?
其实问题就出在这个 d.order_type_code=00901 这个条件上

当有这个条件时候

在这里插入图片描述

全文扫描

没有这个条件的时候

在这里插入图片描述

从sql的执行顺序来分析:

SELECT  * 

 from t_item_detail a

 left join t_order_detail d on a.order_code=d.order_code

 left join t_connection b on a.unique_code = b.funds_unique 

 left join t_capital_detail c on b.capital_unique = c.unique_code 

 where item_receipt_disbursement=1 and a.is_deleted=0

  and order_type_code=00901 group by a.unique_code LIMIT 10 

 

这里面的执行顺序为

1.from

2.on

3.join

4.where

5.select

6.group by

7.limit

写的顺序:select … from… where… group by… having… order by… limit [offset,]

(rows)

执行顺序:from… where…group by… having… select … order by… limit

知道这个,我们再看这个sql

不走索引 有order_type_code条件

SELECT *

from t_item_detail a

left join t_order_detail d on a.order_code=d.order_code

left join t_connection b on a.unique_code = b.funds_unique

left join t_capital_detail c on b.capital_unique = c.unique_code

where item_receipt_disbursement=1 and a.is_deleted=0

and order_type_code=00901 group by a.unique_code LIMIT 10

走索引 没有order_type_code条件

SELECT *

from t_item_detail a

left join t_order_detail d on a.order_code=d.order_code

left join t_connection b on a.unique_code = b.funds_unique

left join t_capital_detail c on b.capital_unique = c.unique_code

where item_receipt_disbursement=1 and a.is_deleted=0

group by a.unique_code LIMIT 10

和走索引有没有order_type_code条件

SELECT *

from t_item_detail a

left join t_order_detail d on a.order_code=d.order_code and d.order_type_cod=‘00901’

left join t_connection b on a.unique_code = b.funds_unique

left join t_capital_detail c on b.capital_unique = c.unique_code

where item_receipt_disbursement=1 and a.is_deleted=0

group by a.unique_code LIMIT 10

会发现 在不走索引有order_type_code条件的那个sql中, 在执行到where的时候,需要去找到条件 order_type_code=00901 ,但是order_type_code这个字段没有索引,所以数据库就去对order_detail进行全表扫描。

因此解决方案,就是给order_type_code加上索引,或者给 left join on就加上条件order_type_code=xxx ,直接过滤掉

因此,谨记,大表查询的时候,where 的条件千万记得加上索引!!!!

————————————————

版权声明:本文为CSDN博主「qq_20009015」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_20009015/article/details/91405186