[英]Which is the best practice to write sql
下面两个查询给出相同的结果。 只想知道在性能方面哪个更好。
查询1:
SELECT N.*
FROM NOTIFICATIONS N
JOIN NOTIFICATION_COMPANY_GROUPS NCG
ON ( N.COMPANY_ID = NCG.COMPANY_ID
AND N.ID = NCG.NOTIFICATION_ID )
JOIN COMPANY_USER_GROUPS CUG
ON ( N.COMPANY_ID = CUG.COMPANY_ID
AND CUG.COMPANY_GROUP_ID = NCG.COMPANY_GROUP_ID )
JOIN NOTIFICATION_PROPERTIES NP ON ( N.COMPANY_ID = NP.COMPANY_ID )
JOIN COMPANY_USER_PROPERTIES CUP
ON ( N.COMPANY_ID = CUP.COMPANY_ID
AND CUP.PROPERTY_ID = NP.PROPERTY_ID )
WHERE N.COMPANY_ID = 2138
AND CUG.COMPANY_USER_ID = 41422
AND CUP.COMPANY_USER_ID = 41422;
查询2:
SELECT N.*
FROM NOTIFICATIONS N
JOIN NOTIFICATION_COMPANY_GROUPS NCG
ON ( N.COMPANY_ID = 2138
AND N.COMPANY_ID = NCG.COMPANY_ID
AND N.ID = NCG.NOTIFICATION_ID )
JOIN COMPANY_USER_GROUPS CUG
ON ( CUG.COMPANY_USER_ID = 41422
AND N.COMPANY_ID = CUG.COMPANY_ID
AND CUG.COMPANY_GROUP_ID = NCG.COMPANY_GROUP_ID )
JOIN NOTIFICATION_PROPERTIES NP ON ( N.COMPANY_ID = NP.COMPANY_ID )
JOIN COMPANY_USER_PROPERTIES CUP
ON ( CUP.COMPANY_USER_ID = 41422
AND N.COMPANY_ID = CUP.COMPANY_ID
AND CUP.PROPERTY_ID = NP.PROPERTY_ID );
我希望性能应该相同,但是您可以使用EXPLAIN
来验证查询计划是否相同。
但是,第一个版本是“正确”的编写方式。 通常, ON
子句只应包含与要联接的表相关的条件,而单个表上的条件应在WHERE
子句中。
唯一的例外是LEFT JOIN
子句 ,其中要连接的表上的条件应位于ON
子句中。 这是因为,如果将它们放在WHERE
子句中,则除非明确检查NULL
,否则将滤除主表中未与联接表匹配的行中的空行。 举个例子:
SELECT ...
FROM T1
LEFT JOIN T2 ON T2.T1_id = T1.id AND T2.someCol = 3
与
SELECT ...
FROM T1
LEFT JOIN T2 ON T2.T1_id = T1.id
WHERE T2.someCol = 3
在第一个版本中, T2.someCol
的测试是在加入之前完成的; 结果将包含T1
中的所有行,但T2
没有匹配行的行将对所有T2
列都为NULL
。 但是第二个版本将没有这些不匹配的行,因为先完成连接,然后执行T2.someCol = 3
测试; 如果没有匹配的T2
行,则T2.someCol
将为NULL
,并且此测试将失败,并且该行将被WHERE
过滤掉。
对于内部联接,无论在联接之前还是之后进行比较,结果都是相等的。 查询计划者应该以最能利用索引的方式对它们进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.