Sql server vs内部联接中的TSQL运算符

Sql server vs内部联接中的TSQL运算符,sql-server,tsql,Sql Server,Tsql,使用SQL Server 2014: 以下语句之间是否存在性能差异 DELETE FROM MyTable where PKID IN (SELECT PKID FROM @TmpTableVar) 及 在您给定的示例中,执行计划将是相同的(最有可能) 但是,拥有相同的执行计划并不意味着它们是这个语句可能拥有的最佳执行计划 我在两个查询中看到的问题是使用了表变量 SQL Server始终假定表变量中只有一行。仅在SQL Server 2014及更高版本中,此假设已更改为100行 因此,无论有多

使用SQL Server 2014:

以下语句之间是否存在性能差异

DELETE FROM MyTable where PKID IN (SELECT PKID FROM @TmpTableVar)


在您给定的示例中,执行计划将是相同的(最有可能)

但是,拥有相同的执行计划并不意味着它们是这个语句可能拥有的最佳执行计划

我在两个查询中看到的问题是使用了
表变量

SQL Server始终假定表变量中只有一行。仅在SQL Server 2014及更高版本中,此假设已更改为100行

因此,无论有多少行,表变量SQL Server都将始终假定在
@TmpTableVar
中有一行

您可以稍微更改代码,让SQL Server更好地了解该表中有多少行,方法是将其替换为
临时表
,并且由于它是表变量中的
pku ID
列,您还可以在该表上创建索引,为sql server提供最佳机会,为该查询提供最佳的执行计划

SELECT PKID INTO #Temp
FROM @TmpTableVar

-- Create some index on the temp table here .....

DELETE FROM MyTable
WHERE EXISTS (SELECT 1 
              FROM #Temp t
              WHERE MyTable.PKID = t.PKID)
注意

In运算符可以正常工作,因为它是表变量中的主键列。但是,如果您曾经在可为NULL的列上使用IN运算符,结果可能会让您感到惊讶,IN运算符在其检查的列中找到NULL值时,会立即变成梨形


我个人更喜欢使用Exists运算符进行此类查询,但内部联接也应该可以正常工作,但如果可以,请避免使用IN运算符

请看一下每个项目的执行计划。在这种情况下,它们可能是相同的。执行计划基于当前的统计数据。它们今天可能是相同的,但以后会改变。这就是为什么我要寻找更广泛的规则。我做了一些测试,这两个测试几乎在所有情况下都是相似的,以澄清:
EXPLAIN
动词用于获取执行计划信息。但是,即使使用不同的统计数据,在运行时统计数据也是相同的。不知道你所说的更广泛的规则是什么意思??谢谢你的帮助。@tableVariables的行数是否也适用于内部连接方法?我想把内部连接看作是更安全的方法。不是问题,是的,它可以导致SQLServer提出一个效率较低的执行计划,因为SQLServer假定在该表中只有一行,主键列上的连接应该只返回一行。但事实并非如此,因此应避免在此类场景中使用表变量。
SELECT PKID INTO #Temp
FROM @TmpTableVar

-- Create some index on the temp table here .....

DELETE FROM MyTable
WHERE EXISTS (SELECT 1 
              FROM #Temp t
              WHERE MyTable.PKID = t.PKID)