SQL优化规则_12_Join相关

不建议对等值查询列使用GROUP BY

  • Content:GROUP BY中的列在前面的WHERE条件中使用了等值查询,对这样的列进行GROUP BY意义不大。
  • Case:
select film_id, title from film where release_year='2006' group by release_year

JOIN语句混用逗号和ANSI模式

  • Content:表连接的时候混用逗号和ANSI JOIN不便于人类理解,并且MySQL不同版本的表连接行为和优先级均有所不同,当MySQL版本变化后可能会引入错误。
  • Case:
select c1,c2,c3 from t1,t2 join t3 on t1.c1=t2.c1,t1.c3=t3,c1 where id>1000

同一张表被连接两次

  • Content:相同的表在FROM子句中至少出现两次,可以简化为对该表的单次访问。
  • Case:
select tb1.col from (tb1, tb2) join tb2 on tb1.id=tb.id where tb1.id=1

OUTER JOIN失效

  • Content:由于WHERE条件错误使得OUTER JOIN的外部表无数据返回,这会将查询隐式转换为 INNER JOIN 。如:select c from L left join R using(c) where L.a=5 and R.b=10。这种SQL逻辑上可能存在错误或程序员对OUTER JOIN如何工作存在误解,因为LEFT/RIGHT JOIN是LEFT/RIGHT OUTER JOIN的缩写。
  • Case:
select c1,c2,c3 from t1 left outer join t2 using(c1) where t1.c2=2 and t2.c3=4

不建议使用排它JOIN

  • Content:只在右侧表为NULL的带WHERE子句的LEFT OUTER JOIN语句,有可能是在WHERE子句中使用错误的列,如:“… FROM l LEFT OUTER JOIN r ON l.l = r.r WHERE r.z IS NULL”,这个查询正确的逻辑可能是 WHERE r.r IS NULL。
  • Case:
select c1,c2,c3 from t1 left outer join t2 on t1.c1=t2.c1 where t2.c2 is null

减少JOIN的数量

  • Content:太多的JOIN是复杂的裹脚布式查询的症状。考虑将复杂查询分解成许多简单的查询,并减少JOIN的数量。
  • Case:
select bp1.p_id, b1.d_d as l, b1.b_id from b1 join bp1 on (b1.b_id = bp1.b_id) left outer join (b1 as b2 join bp2 on (b2.b_id = bp2.b_id)) on (bp1.p_id = bp2.p_id ) join bp21 on (b1.b_id = bp1.b_id) join bp31 on (b1.b_id = bp1.b_id) join bp41 on (b1.b_id = bp1.b_id) where b2.b_id = 0

将嵌套查询重写为JOIN通常会导致更高效的执行和更有效的优化

  • Content:一般来说,非嵌套子查询总是用于关联子查询,最多是来自FROM子句中的一个表,这些子查询用于ANY、ALL和EXISTS的谓词。如果可以根据查询语义决定子查询最多返回一个行,那么一个不相关的子查询或来自FROM子句中的多个表的子查询就被压平了。
  • Case:
SELECT s,p,d FROM tbl WHERE p.p_id = (SELECT s.p_id FROM tbl WHERE s.c_id = 100996 AND s.q = 1 )

不建议使用联表更新

  • Content:当需要同时更新多张表时建议使用简单SQL,一条SQL只更新一张表,尽量不要将多张表的更新在同一条SQL中完成。
  • Case:
UPDATE users u LEFT JOIN hobby h ON u.id = h.uid SET u.name = 'pianoboy' WHERE h.hobby = 'piano';

不要使用跨DB的Join查询

  • Content:一般来说,跨DB的Join查询意味着查询语句跨越了两个不同的子系统,这可能意味着系统耦合度过高或库表结构设计不合理。
  • Case:
SELECT s,p,d FROM tbl WHERE p.p_id = (SELECT s.p_id FROM tbl WHERE s.c_id = 100996 AND s.q = 1 )
    原文作者:在水一方_Eric
    原文地址: https://www.jianshu.com/p/41c7b4c7af35
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞