连接在运行时是否优化到where子句?


14

当我写这样的查询...

select *
from table1 t1
join table2 t2
on t1.id = t2.id

SQL优化器不确定将其翻译为...吗?

select *
from table1 t1, table2 t2
where t1.id = t2.id

从本质上讲,SQL Server中的Join语句只是编写sql的一种简便方法吗?还是在运行时实际使用?

编辑:我几乎总是并且几乎总是会使用Join语法。我很好奇发生了什么。


1
您能否详细说明“差不多”?什么时候使用旧式语法,为什么?
亚伦·伯特兰

2
它确实有差别的一个边缘的情况是,如果你(不建议使用)加GROUP BY ALL
马丁·史密斯

@MartinSmith有人GROUP BY ALL故意使用吗?:-)
亚伦·伯特兰

@AaronBertrand-我对此表示怀疑!认为我从未见过有人使用过它。
马丁·史密斯

Answers:


20

这些内部崩溃为同一件事。前者是你应该经常写的。更重要的是,为什么重要?在执行计划和性能方面,它们是相同的(假设您不搞乱它,使用惰性的老式语法更容易做到)。

这里是证明使用的AdventureWorks没有CROSS JOINfilter回事。


显式联接:

在此处输入图片说明


隐式联接:

在此处输入图片说明


看,妈!相同的计划,相同的结果,没有任何交叉联接或过滤器。

(为清楚起见,SELECT在两种情况下,对运算符的警告都是影响基数的隐式转换,在两种情况下均与联接无关。)


20

严格来说,两种形式之间查询优化器的输入有所不同:

-- Input tree (ISO-89)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM 
    Production.Product AS p,
    Production.ProductInventory AS inv
WHERE
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

ISO-89输入树

-- Input tree (ISO-92)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM Production.Product AS p
JOIN Production.ProductInventory AS inv ON
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

ISO-92输入树

如您所见,ON子句谓词使用现代语法紧密绑定到连接。使用较旧的语法时,存在逻辑交叉联接,后跟关系选择(行过滤器)。

查询优化器几乎总是在优化过程中将关系选择折叠到联接中,这意味着这两种形式很可能会产生等效的查询计划,但是并没有实际的保证。


4

对于内部联接,它们可以互换,但是对于外部联接,它们具有不同的含义-ON是匹配的,WHERE是简单的过滤。因此,最好在ON上坚持正确的JOIN语法匹配。


4

好吧,我很好奇,所以我做了一个测试。我得到了以下的实际执行计划。

select * 
from sys.database_principals prin, sys.database_permissions perm
WHERE prin.principal_id = perm.grantee_principal_id

select * 
from sys.database_principals prin
JOIN sys.database_permissions perm
    ON prin.principal_id = perm.grantee_principal_id

我逐个对象地比较了它们,它们是相同的。因此,至少对于一个非常简单的示例,他们得出了相同的结论。我还检查了统计数据IO和时间,它们足够接近以至于是同一件事。

话虽如此,您应该使用JOIN语法,因为它更易于阅读,并且您出错的可能性较小,尤其是在复杂的查询中。从SQL Server 2005开始,用于联接的*=/ =*语法OUTER已被删除。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.