我目前遇到查询的性能问题(比下面的示例更复杂)。最初查询将运行并占用30秒,然后当我关闭使用表变量来使用临时表时,速度会降低到几秒钟。
这是一个使用表变量的精简版:
-- Store XML into tables for use in query
DECLARE @tCodes TABLE([Code] VARCHAR(100))
INSERT INTO
@tCodes
SELECT
ParamValues.ID.value('.','VARCHAR(100)') AS 'Code'
FROM
@xmlCodes.nodes('/ArrayOfString/string') AS ParamValues(ID)
SELECT
'SummedValue' = SUM(ot.[Value])
FROM
[SomeTable] st (NOLOCK)
JOIN
[OtherTable] ot (NOLOCK)
ON ot.[SomeTableID] = st.[ID]
WHERE
ot.[CodeID] IN (SELECT [Code] FROM @tCodes) AND
st.[Status] = 'ACTIVE' AND
YEAR(ot.[SomeDate]) = 2013 AND
LEFT(st.[Identifier], 11) = @sIdentifier
这是带有临时表的版本,它可以更快地执行:
SELECT
ParamValues.ID.value('.','VARCHAR(100)') AS 'Code'
INTO
#tCodes
FROM
@xmlCodes.nodes('/ArrayOfString/string') AS ParamValues(ID)
SELECT
'SummedValue' = SUM(ot.[Value])
FROM
[SomeTable] st (NOLOCK)
JOIN
[OtherTable] ot (NOLOCK)
ON ot.[SomeTableID] = st.[ID]
WHERE
ot.[CodeID] IN (SELECT [Code] FROM #tCodes) AND
st.[Status] = 'ACTIVE' AND
YEAR(ot.[SomeDate]) = 2013 AND
LEFT(st.[Identifier], 11) = @sIdentifier
我对性能的问题通过更改解决了,但我只是不明白为什么它解决了这个问题,并且更愿意知道原因。它可能与查询中的其他内容有关,但我在存储过程中所做的更改(更复杂)是从使用表变量切换到使用临时表。有什么想法吗?
答案 0 :(得分:1)
深入研究表变量和#temp
表之间的差异和相似之处{/ 3}}。
关于你展示的两个查询(未编制索引的表变量与未索引的临时表),我想到了三种可能性。
INSERT ... SELECT
表变量始终是串行的。可以为临时表并行化SELECT
。0
(当表为空时编译它们)从您显示的代码(3)看起来似乎是最可能的解释。
这可以通过在填充表变量后使用OPTION (RECOMPILE)
重新编译语句来解决。