编写sql的最佳实践是什么
下面两个查询给出相同的结果。 只是想知道哪一个性能更好 查询1:编写sql的最佳实践是什么,sql,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 (
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;
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 );
查询2:
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;
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
验证查询计划是否相同
然而,第一个版本是写它的“正确”方式。通常,子句上的应该只包含与作为连接的表相关的条件,而单个表上的条件应该在WHERE
子句中
唯一的例外是在左连接
子句中,其中要连接的表上的条件应该在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
过滤掉
对于内部联接,无论是在联接之前还是之后进行比较,结果都是等效的。查询计划员应以最能利用索引的方式对其进行排序。查询计划员应同等对待这两种表单-查看特定SQL实现中的查询计划,以查看是否有任何意外情况。话虽如此,我建议所有(且仅)连接术语都位于..
位的中,其他所有术语都位于的WHERE
中。也就是说,我推荐第一种形式——我发现它更容易阅读/理解,更容易生成、修改或集成到外部查询中。为什么不测量它呢?剩下的:试着写下尽可能容易理解的陈述(这是一个品味/思维方式的问题)。这将更容易获得语义正确的语句(并维护它们)。只有在遇到性能问题时,才尝试其他方法。(“过早优化是万恶之源”,D.E.Knuth说)说“唯一例外”的部分应该用粗体字;这是非常重要的,也是很多bug的来源。我不知道关于左连接的部分。在这种情况下,这是在简单地移动固定条款(例如,cup.company\u user\u id=41422
)吗?或者这是专门指连接条件吗?我已经为左连接添加了一个示例。