广告位联系
返回顶部
分享到

查一次left join没有走索引以及原因分析介绍

Mysql 来源:互联网 作者:佚名 发布时间:2023-11-29 21:45:05 人浏览
摘要

查一次left join没有走索引的原因 线上有个查询sql,原来是inner join 查询没有问题,后来应业务要求改成left join之后, 查询时间就暴涨了 需要长达24s 通过explain分析,发现订单表没有走索

查一次left join没有走索引的原因

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

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

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

具体sql如下

1

2

3

4

5

6

7

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 说明并没有走索引。

这里首先看关联条件

1

2

from t_item_detail a

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

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

两张表的order_code字段均有索引。

其次再看, 如果两个字段或者两张表的编码不同,也会导致索引失效。

但是这两张表的编码和字段编码也均相同,因此也排除掉。

最后发现,

如果写成

1

2

3

4

5

6

7

explain SELECT  *

from t_item_detail a

left join t_order_detail d on a.order_code=d.order_code  and d.order_type_code=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

也就是将原来在where条件的order_type_code=00901 写到left join的条件后面

d的索引就生效了,所有的索引都生效了。

查询时间也从原来的24秒 变成了不到1秒。

这是为什么呢?

其实问题就出在这个 d.order_type_code=00901 这个条件上

当有这个条件时候

全文扫描

没有这个条件的时候

从sql的执行顺序来分析:

1

2

3

4

5

6

7

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条件

1

2

3

4

5

6

7

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条件

1

2

3

4

5

6

7

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条件

1

2

3

4

5

6

7

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 的条件千万记得加上索引!!!!


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计