为了账号安全,请及时绑定邮箱和手机立即绑定

distinct和order by共存对索引选择的影响

标签:
MySQL


程序需要找出产品表中最新添加的状态为可用的20个产品用于客户展示

sql语句如下

SELECT DISTINCT p.products_id, p.sj_id, p.px_id, p.products_model, p.products_image, pd.products_name

FROM products AS p LEFT JOIN products_description AS pd ON pd.products_id=p.products_id

WHERE 1 AND p.products_status=1 ORDER BY p.products_date_added DESC LIMIT 0, 20;

功能上线后,发现非常慢。

explian

+----+-------------+-------+------+---------------+---------+---------+-----------------------------+-------+----------------------------------------------+

| id | select_type | table | type | possible_keys | key     | key_len | ref                         | rows  | Extra                                        |

+----+-------------+-------+------+---------------+---------+---------+-----------------------------+-------+----------------------------------------------+

|  1 | SIMPLE      | p     | ALL  | NULL          | NULL    | NULL    | NULL                        | 71180 | Using where; Using temporary; Using filesort |

|  1 | SIMPLE      | pd    | ref  | PRIMARY       | PRIMARY | 4       | banggood_work.p.products_id |     1 |                                              |

+----+-------------+-------+------+---------------+---------+---------+-----------------------------+-------+----------------------------------------------+

发现products_date_added索引并没有被用上(products_date_added字段有索引,99.9%以上为products_status=1的产品),应该来讲,mysql优化器此时会选择products_date_added字段上的索引.

仔细观察sql发现有distinct关键字,而这语句根本不需要distinct.

此时mysql会将整个products取出来,进行去重,导致了全表扫!

将distinct去掉,再explain

+----+-------------+-------+-------+---------------+---------------------+---------+-----------------------------+------+-------------+

| id | select_type | table | type  | possible_keys | key                 | key_len | ref                         | rows | Extra       |

+----+-------------+-------+-------+---------------+---------------------+---------+-----------------------------+------+-------------+

|  1 | SIMPLE      | p     | index | NULL          | products_date_added | 8       | NULL                        |   20 | Using where |

|  1 | SIMPLE      | pd    | ref   | PRIMARY       | PRIMARY             | 4       | banggood_work.p.products_id |    1 |             |

+----+-------------+-------+-------+---------------+---------------------+---------+-----------------------------+------+-------------+

发现mysql已经智能的选择了products_date_added索引,尽管该字段不再where条件上。

总结

1. mysql选择索引并不一定只会在join条件和where条件上选择,有时候也会智能的选择order by、group by上的字段

2.distinct会干扰order by智能选择索引。distinct和order by共存对索引是有影响的,一般是在非where条件选择索引的情况下

3. 请慎重使用distinct,不需要尽量不要用!另外可以参考我的另外一篇博文http://qdjalone.blog.51cto.com/1222376/1360112

©著作权归作者所有:来自51CTO博客作者justforqdj的原创作品,如需转载,请注明出处,否则将追究法律责任

mysql优化order by 优化mysql sql调优记录


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消