查一次left join没有走索引以及原因分析 |
您所在的位置:网站首页 › mysql字段添加索引 › 查一次left join没有走索引以及原因分析 |
查一次left join没有走索引以及原因分析
查一次left join没有走索引的原因 线上有个查询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字段是否加索引. 两张表的order_code字段均有索引。 其次再看, 如果两个字段或者两张表的编码不同,也会导致索引失效。 但是这两张表的编码和字段编码也均相同,因此也排除掉。 最后发现, 如果写成 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的执行顺序来分析: 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.from2.on3.join4.where5.select6.group by7.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 的条件千万记得加上索引!!!! 总结 以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程宝库。 下一节:IDEA连接MySQL数据库并执行SQL语句使用数据图文详解MySQL教程一、IDEA连接MySQL数据库(一)首先新建普通Java项目(二)连接数据库1、点击右侧DataBase2、点击加号,找到MySQL,添加数据库3、输入用户名和密码 ... |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |