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

不要随随便便的distinct和order by

标签:
MySQL


有客户反应网站后台订单相关查询非常慢,通过程序拿到了相关sql

explain

explain SELECT DISTINCT(o.orders_id), o.oa_order_id, customers_email_address, o.order_type, ot.text AS total_value, o.track_number, o.date_purchased, o.orders_status, o.specialOperate, o.isSpecialParent, o.pay_ip, o.supply_id, o.products_center_id, o.split_code, o.is_import, o.shipDays,o.delivery_country,o.use_coupon ,o.payment_method FROM orders AS o LEFT JOIN orders_total AS ot ON ot.orders_id=o.orders_id AND ot.class='ot_total' WHERE 1  AND o.is_delete = 0  AND o.date_purchased >= '2013-09-30 10:00:00' AND (o.specialOperate = 0 OR o.isSpecialParent=1) ORDER BY date_purchased DESC, orders_id DESC LIMIT 0, 20;

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

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

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

|  1 | SIMPLE      | o     | range | date_purchased                   | date_purchased             | 9       | NULL                 | 606632 | Using where; Using temporary; Using filesort |

|  1 | SIMPLE      | ot    | ref   | idx_orders_total_orders_id,class | idx_orders_total_orders_id | 4       | banggood.o.orders_id |     19 |                                              |

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

2 rows in set (0.05 sec)

发现索引使用正常,执行状态中发现有Copying to tmp table on disk状态,执行时间超过50s。

使用profiling发现Copying to tmp table on disk占用了大部分性能。

仔细查看该语句并和开发讨论,发现distinct和ORDER BY date_purchased DESC, orders_id DESC中,distinct关键字可以省略,而且ORDER BY date_purchased DESC, orders_id DESC可以去掉后面的orders_id desc(开发对多个字段排序不理解).

去掉后,再次explain

mysql> EXPLAIN

    -> SELECT o.orders_id, o.oa_order_id, customers_email_address, o.order_type, ot.text AS total_value, o.track_number, o.date_purchased, o.orders_status, o.specialOperate, o.isSpecialParent, o.pay_ip, o.supply_id, o.products_center_id, o.split_code, o.is_import, o.shipDays,o.delivery_country,o.use_coupon ,o.payment_method FROM orders AS o LEFT JOIN orders_total AS ot ON ot.orders_id=o.orders_id AND ot.class='ot_total' WHERE 1  AND o.is_delete = 0  AND o.date_purchased >= '2013-09-30 10:00:00' AND (o.specialOperate = 0 OR o.isSpecialParent=1)

    -> ORDER BY date_purchased DESC LIMIT 0, 20;

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

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

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

|  1 | SIMPLE      | o     | range | date_purchased                   | date_purchased             | 9       | NULL                 | 606632 | Using where |

|  1 | SIMPLE      | ot    | ref   | idx_orders_total_orders_id,class | idx_orders_total_orders_id | 4       | banggood.o.orders_id |     19 |             |

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

2 rows in set (0.01 sec)

索引使用情况不变,但是下面的profiling,发现结果瞬间出来,执行时间不过0.003s,而且已经没有了Copying to tmp table on disk状态。

总结:1.因为distinct关键字需要对结果集进行去重,如果天然无重复,是不需要加上去重关键字的,上面的例子结果集有将近百万,去重字段又多,在tmp_table_size以及sort_buffer_size中排序已经不够用,所以将结果集复制到磁盘,严重影响速度

2. order by a,b 开发人员很喜欢用类似的语句,尽管对功能没有多大作用

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

mysql优化distinctmysql sql调优记录


点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消