专栏名称: 高效运维
高效运维公众号由萧田国及朋友们维护,经常发布各种广为传播的优秀原创技术文章,关注运维转型,陪伴您的运维职业生涯,一起愉快滴发展。
目录
相关文章推荐
51好读  ›  专栏  ›  高效运维

8种常被忽视的SQL错误用法

高效运维  · 公众号  · 运维  · 2017-05-05 07:30

正文

请到「今天看啥」查看全文


UPDATE operation o
JOIN  (SELECT o.id,
o.status
FROM   operation o
WHERE  o.group = 123
AND o.status NOT IN ( 'done' )
ORDER  BY o.parent,
o.id
LIMIT  1) t
ON o.id = t.id
SET    status = 'applying'

执行计划简化为:

4. 混合排序

MySQL 不能利用索引进行混合排序。但在某些场景,还是有机会使用特殊方法提升性能的。

SELECT *
FROM   my_order o
INNER JOIN my_appraise a ON a.orderid = o.id
ORDER  BY a.is_reply ASC,
a.appraise_time DESC
LIMIT  0, 20

执行计划显示为全表扫描:

由于 is_reply 只有0和1两种状态,我们按照下面的方法重写后,执行时间从1.58秒降低到2毫秒。

SELECT *
FROM   ((SELECT *
FROM   my_order o
INNER JOIN my_appraise a
ON a.orderid = o.id
AND is_reply = 0
ORDER  BY appraise_time DESC
LIMIT  0, 20)
UNION ALL
(SELECT *
FROM   my_order o
INNER JOIN my_appraise a
ON a.orderid = o.id
AND is_reply = 1
ORDER  BY appraise_time DESC
LIMIT  0, 20)) t
ORDER  BY  is_reply ASC,
appraisetime DESC
LIMIT  20;

5. EXISTS语句

MySQL 对待 EXISTS 子句时,仍然采用嵌套子查询的执行方式。如下面的 SQL 语句:

SELECT *
FROM   my_neighbor n
LEFT JOIN my_neighbor_apply sra
ON n.id = sra.neighbor_id
AND sra.user_id = 'xxx'
WHERE  n.topic_status < 4
AND EXISTS(SELECT 1
FROM   message_info m
WHERE  n.id = m.neighbor_id
AND m.inuser = 'xxx')
AND n.topic_type <> 5

执行计划为:

去掉 exists 更改为 join,能够避免嵌套子查询,将执行时间从1.93秒降低为1毫秒。

SELECT *
FROM   my_neighbor n
INNER JOIN message_info m
ON n.id = m.neighbor_id
AND m.inuser = 'xxx'
LEFT JOIN my_neighbor_apply sra
ON n.id = sra.neighbor_id
AND sra.user_id = 'xxx'
WHERE  n.topic_status < 4
AND n.topic_type <> 5

新的执行计划:







请到「今天看啥」查看全文