以下两个查询给出相同的结果。 只是想知道哪一个在性能方面更好。
查询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 );
答案 0 :(得分:7)
我希望性能应该相同,但您可以使用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
中没有匹配行的行将包含所有NULL
列的T2
。但是第二个版本没有任何这些不匹配的行,因为首先完成连接,然后执行T2.someCol = 3
测试;如果没有匹配的T2
行,T2.someCol
将为NULL
,此测试将失败,该行将被WHERE
过滤掉。
在内部联接的情况下,在加入之前或之后进行比较并不重要,结果是等效的。查询计划程序应该以最有利于索引的方式对它们进行排序。