ON 与 WHERE 上的索引性能

Eri*_*edt 26 index join sql-server t-sql table

我有两张桌子

@T1 TABLE
(
    Id INT,
    Date DATETIME
)

@T2 TABLE
(
    Id INT,
    Date DATETIME
)
Run Code Online (Sandbox Code Playgroud)

这些表在 (Id, Date) 上有一个非聚集索引

我加入这些表

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
WHERE 
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()
Run Code Online (Sandbox Code Playgroud)

这也可以写成

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
    AND
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()
Run Code Online (Sandbox Code Playgroud)

我的问题是,这两个查询中哪一个提供了更好的性能,为什么?或者他们是平等的?

Tom*_*m V 32

性能将是相同的。优化器将识别出这一点并创建相同的计划。

另一方面,我不会说它们是平等的。第一种形式中的问题是远更具有可读性和普遍预期。

对于使用我手头的一些表的示例,无论我如何编写查询,您都可以看到执行计划完全相同。

您应该能够确定您自己的表和数据集的查询计划,这样您就可以了解在您的情况下会发生什么。

SELECT * FROM salestable , custtable 
WHERE salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable 
JOIN  custtable 
ON salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable JOIN custtable 
ON salestable.custaccount = custtable.accountnum 
WHERE salestable.dataareaid = custtable.dataareaid
Run Code Online (Sandbox Code Playgroud)

给出这些执行计划

在此处输入图片说明


Mar*_*ith 22

它们在语义上是相同的,优化器应该可以轻松识别这一事实并生成相同的计划。

我倾向于将引用两个表的ON条件放在WHERE.

OUTER JOINS然而,对于移动条件会影响语义。


小智 7

在简单的情况下,它会是一样的。但是,我已经看到具有多个连接的非常复杂的查询具有明显不同的计划。我最近在研究的一个表开始时有将近 600 万行连接到大约 20 个不同的表。只有该表的第一个联接是联接,所有其他联接都是左外联接。where 子句中的过滤器参数化如下:

WHERE table1.begindate >= @startdate AND table1.enddate < @enddate 
Run Code Online (Sandbox Code Playgroud)

此过滤器在计划的后期使用,而不是在早期使用。当我将这些条件移到第一个内部联接时,计划发生了巨大变化,因为在计划的早期应用了过滤器以限制结果集,并且我的 CPU 和运行时间下降了大约 310%。因此,与许多 SQL Server 问题一样,这取决于。

  • 你能否添加更多细节——也许是执行计划图的截图——因为你的答案似乎与所有其他答案相矛盾? (2认同)
  • 计划是否显示优化器超时? (2认同)