Sql JOIN比WHERE快吗?
假设我有两个链接的表(一个表与另一个表之间有外键): 我知道,这不是最聪明的做事方式,但这是我能想到的最好的例子 现在,我想得到所有超过500个视图的文档。我想到的两个解决方案是: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 或: 这两个查询是等价的,还是有一种方法比另一种好得多?若然,原因为何 编辑:正如回答中所要
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模式,您将无法实现不同类型的连接(内部连接与外部连接),这将导致维护噩梦(并且,如果在一个查询中将两者结合在一起,则会出现一些不直观的行为)
(步骤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