Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写sql的最佳实践是什么_Sql - Fatal编程技术网

编写sql的最佳实践是什么

编写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 (

下面两个查询给出相同的结果。 只是想知道哪一个性能更好

查询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;
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
)吗?或者这是专门指连接条件吗?我已经为左连接添加了一个示例。