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

Mr.*_*Ant 15 join sql-server optimization t-sql

当我写这样的查询时......

select *
from table1 t1
join table2 t2
on t1.id = t2.id
Run Code Online (Sandbox Code Playgroud)

SQL 优化器,不确定这是否是正确的术语,是否将其转换为...

select *
from table1 t1, table2 t2
where t1.id = t2.id
Run Code Online (Sandbox Code Playgroud)

本质上,SQL Server 中的 Join 语句只是一种更简单的编写 sql 的方法吗?或者它实际上是在运行时使用的?

编辑:我几乎总是,而且几乎总是,使用 Join 语法。我只是好奇会发生什么。

Aar*_*and 21

这些通常会在内部崩溃为同一件事。前者是你应该总是写的,恕我直言。更重要的是,它为什么重要?它们在执行计划和性能方面是相同的(假设你没有把它搞砸,用懒惰的旧式语法更容易做到)。

这是使用 AdventureWorks 的证据,证明没有CROSS JOIN并且filter还在继续。


显式连接:

在此处输入图片说明


隐式连接:

在此处输入图片说明


看,妈!相同的计划,相同的结果,在任何地方都看不到交叉连接或过滤器。

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


Pau*_*ite 21

严格来说,这两种形式在查询优化器的输入上是有区别的:

-- 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);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

ISO-92 输入树

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

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