哪个是编写sql的最佳实践

时间:2014-02-20 06:56:17

标签: 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 );

1 个答案:

答案 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过滤掉。

在内部联接的情况下,在加入之前或之后进行比较并不重要,结果是等效的。查询计划程序应该以最有利于索引的方式对它们进行排序。