Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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 JOIN比WHERE快吗?_Sql_Performance_Join_Where Clause - Fatal编程技术网

Sql JOIN比WHERE快吗?

Sql JOIN比WHERE快吗?,sql,performance,join,where-clause,Sql,Performance,Join,Where Clause,假设我有两个链接的表(一个表与另一个表之间有外键): 我知道,这不是最聪明的做事方式,但这是我能想到的最好的例子 现在,我想得到所有超过500个视图的文档。我想到的两个解决方案是: SELECT * FROM Document, DocumentStats WHERE DocumentStats.Id = Document.Id AND DocumentStats.NbViews > 500 或: 这两个查询是等价的,还是有一种方法比另一种好得多?若然,原因为何 编辑:正如回答中所要

假设我有两个链接的表(一个表与另一个表之间有外键):

我知道,这不是最聪明的做事方式,但这是我能想到的最好的例子

现在,我想得到所有超过500个视图的文档。我想到的两个解决方案是:

SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500
或:

这两个查询是等价的,还是有一种方法比另一种好得多?若然,原因为何


编辑:正如回答中所要求的,这个问题是针对SQL Server的,但我想知道它是否与其他数据库引擎(MySQL等)不同。

至少在MySQL中,它们都将针对相同的查询进行优化。

理论上,不,不应该更快。查询优化器应该能够生成相同的执行计划。但是,一些数据库引擎可以为其中一个生成更好的执行计划(对于这样一个简单的查询不太可能,但对于足够复杂的查询则不太可能)。您应该测试这两个查询并查看(在数据库引擎上)。

在MSSQL中,两个查询都编译到同一个执行计划中,因此没有区别。更多的是关于可读性——我认为连接更容易阅读,所以我使用它。

如果不局限于目标数据库,就无法正确回答这个问题

对于MS-SQL,两个查询都会产生相同的执行计划,但请记住:

SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500

这是非常危险的,因为很容易忘记WHERE子句中的连接条件,并以一个糟糕的交叉连接结束

使用内部联接语法是一种“标准”,尽管实际上是等效的。应该使用它的主要原因是为了清晰和移动性,因为它与外部连接语法一致。

使用Sqlite时:where语法稍微快一点,因为Sqlite在执行查询之前首先将连接语法转换为where语法。

我想这也没有什么区别。为了确保您可以检查这两个查询的解释计划是否相同。为了查看MySQL中的解释计划,您必须在语句之前添加“explain”关键字,例如:

EXPLAIN
SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500
我确信MSSQL中也存在一个等价物

顺便说一下:
这看起来像是一个1:1的关系,所以我只想在文档表中直接包含nbviews属性,因此您可以保存联接。

显式联接更容易维护,因为查询的意图更清楚。此外,它们也不会受到意外交叉连接的影响,因此如果查询中有交叉连接,则维护人员知道它本来就在那里


如果需要使用外部联接,您应该知道*=语法在SQL Server中已被弃用,并且很快将被删除。此外,它目前并非始终按预期运行,可能不会给出正确的结果,因此不应使用。混合使用显式外部联接和where子句联接(隐式联接)会使维护人员更难阅读和理解查询。

如果您专门谈论SQL Server,那么您肯定应该使用内部联接语法。除了(个人意见提醒!)更易于阅读和更清晰的意图之外,从SQLServer2005开始,外部联接没有等效的语法。在2005年,默认情况下不支持*=和=*语法——您需要启用兼容模式来支持它。它最终将被删除,可能会在下一个版本中删除(也可能不会!)

这意味着:

  • 如果需要将查询从内部联接更改为外部联接,则需要重写它(argh)或启用兼容模式(yuk)
  • 如果没有compat模式,您将无法实现不同类型的连接(内部连接与外部连接),这将导致维护噩梦(并且,如果在一个查询中将两者结合在一起,则会出现一些不直观的行为)
还要注意的是,与普遍的看法相反,这两者并不等同。有些事情要尴尬得多,有些根本不可能。Kalen Delaney的Inside SQL Server 2000包含了一些示例;不确定较新版本是否支持,因为该连接语法无论如何都不推荐使用。

与“WHERE”相比,“join”的性能。。。一切都取决于数据库引擎为您优化查询的能力。它将考虑可能返回的列中的任何索引,并考虑WHO和联接子句的性能也会归结为物理数据库文件本身及其碎片级别,甚至存储数据库文件的存储技术。

SQL server按以下顺序执行查询(这将使您了解WHERE和JOIN子句的功能)

Microsoft SQL Server查询进程顺序 以下内容摘自有关MicrosoftSQLServer的优秀丛书《MicrosoftSQLServer2005内部:T-SQL查询》,可以找到

(步骤8)选择(步骤9)不同(步骤11)
(步骤1)从左_表
(步骤3) 连接条件下的连接类型连接右表(步骤2)(步骤4),其中 其中,_条件
(步骤5)按组分组_按_列表
(步骤6),且[CUBE | ROLLUP]
(步骤7)具有 拥有条款(第10步)按顺序列表


什么数据库?Ms SQL、MySQL、SQLite、Oracle…?这被称为显式连接与隐式连接,之前有人问过:@Theo:MSSQL主要是,但我也会对其他连接感兴趣@谢谢,我不知道是这样的电话。我尝试使用JOIN vs WHERE进行搜索,但找不到答案。在不同搜索条件下在系统中使用两次也无妨。:)+1用于推荐测试OPs特定案例。我同意特朗普的观点。我经常尝试查询的JOIN和WHERE版本,以查看哪个版本的性能最好。有时加入更快,有时在哪里-这取决于查询。啊,喜欢这个答案!通过反复试验发现,SQL S.首先在上执行,然后在何处执行,最后执行。通常不会
SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500
EXPLAIN
SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500