我想知道将现有表复制到临时表是否会导致与动态SQL相比性能更差。
具体而言,我想知道我是否应该期望以下两个SQL Server存储过程之间的性能不同:
CREATE PROCEDURE UsingDynamicSQL
(
@ID INT ,
@Tablename VARCHAR(100)
)
AS
BEGIN
DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = 'Insert into Table2 Select Sum(ValColumn) From '
+ @Tablename + ' Where ID=' + @ID
EXEC(@SQL)
END
CREATE PROCEDURE UsingTempTable
(
@ID INT ,
@Tablename Varachar(100)
)
AS
BEGIN
Create Table #TempTable (ValColumn float, ID int)
DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = 'Select ValColumn, ID From ' + @Tablename
+ ' Where ID=' + @ID
INSERT INTO #TempTable
EXEC ( @SQL );
INSERT INTO Table2
SELECT SUM(ValColumn)
FROM #TempTable;
DROP TABLE #TempTable;
END
我问这个,因为我目前正在使用后一种方式的过程构建,我在开始时创建许多临时表作为现有表的简单摘录,然后使用这些临时表。 我可以通过删除临时表并使用动态SQL来提高存储过程的性能吗?在我看来,动态SQL版本对程序来说更加丑陋 - 因此我首先使用了临时表。
答案 0 :(得分:1)
表变量会遇到性能问题,因为查询优化器总是假定它们中只有一行。如果你有表变量持有> 100行,我将它们切换到临时表。
将动态sql与EXEC(@sql)
而不是exec sp_executesql @sql
一起使用会阻止查询计划被缓存,这可能会影响性能。
但是,您在两个查询上都使用动态SQL。唯一的区别是第二个查询首先加载到表变量,然后加载到最终表中。使用您拥有的第一个存储过程,但切换到sp_executesql。
答案 1 :(得分:0)
在发布的查询中,临时表是额外的写入 它没有帮助。
不要只是查询查询计划的时间 如果您有两个查询,查询计划将告诉您拆分。
表变量和临时表之间存在差异 临时表更快 - 查询优化器使用临时表执行更多操作
临时表可以在一些情况下提供帮助
select的输出将被多次使用
您实现了输出,因此它只执行一次
你看到这是一个昂贵的CTE,经过多次评估
人们错误地认为CTE只执行一次 - 不仅仅是语法
查询优化器需要帮助
一个例子
您正在一个具有多个条件的大型表上进行自联接,并且某些条件会消除大多数行
对#temp的查询可以过滤行并减少连接条件的数量
答案 2 :(得分:0)
我同意其他人的意见,你总是需要对它们进行测试......我在这里把它放在答案中,这样就更清楚了。
如果您的索引设置非常适合最终查询,那么转到临时表可能只是额外的工作。
如果情况并非如此,对临时表的预过滤可能会更快,也可能不会更快
你可以在极端情况下预测它 - 如果你从一百万到十几行过滤,我敢打赌它有帮助。
但是否则,如果不尝试就可能真的很难知道。
我同意你的看法,维护也是一个问题,许多动态sql需要考虑维护成本。