我有一个临时表,用于存储过程中的中间计算。
这是代码段:
CREATE TABLE #Updates
(
ID int not null,
ID2 int not null,
ID3 int not null
);
-- Do some operations and updates
IF OBJECT_ID('tempdb..#Updates','U') IS NOT NULL
DROP TABLE #Updates;
因为我们一天要做很多事情。它会导致SQL Server性能问题。
我想把上面的代码改成
IF OBJECT_ID('tempdb..#Updates','U') IS NULL
BEGIN
CREATE TABLE #Updates
(
ID int not null,
ID2 int not null,
ID3 int not null
);
END
-- Do some operations and updates
IF OBJECT_ID('tempdb..#Updates','U') IS NOT NULL
DELETE FROM #Updates
我想知道新的更改是否会提高SQL Server的性能。如果有更好的方法,也请告诉我。
答案的简短版本
- 取消对临时表是否存在的检查-这些检查只在开发和手动执行部分代码时有用
- 除非从临时表中删除,然后在中添加新数据,否则在存储过程完成时,只需自然删除临时表即可
- 还要考虑主键和/或索引是否会有所帮助
例如,我在下面评论了你不需要的东西,并在ID 上添加了一个主键
-- IF OBJECT_ID('tempdb..#Updates','U') IS NULL
-- BEGIN
CREATE TABLE #Updates (
ID int not null PRIMARY KEY,
ID2 int not null,
ID3 int not null
);
-- END
<Do some operations and updates>
-- IF OBJECT_ID('tempdb..#Updates','U') IS NOT NULL
-- DELETE FROM #Updates
如果在该存储过程中
- 创建临时表
- 在其中插入值/数据
- 通过Delete from#更新删除其中的所有内容
- 在其中插入新值
则使用TRUNCATE TABLE #Updates
将略快于从中删除。
解释/更长的答案:
临时表格为
- 仅在当前会话/范围内可用,并且
- 存储过程完成时删除
如果同时运行存储过程两次,每个存储过程都将创建、使用、然后删除自己的临时表,并且彼此无法访问它们。
在提高性能方面
- 如果您只使用过该表一次(例如,您创建它,插入它,在联接中使用它,然后完成它(,您可以将SQL移动到您正在使用的联接的一部分(例如,绕过创建临时表的需要(。这避免了创建临时表的成本,但可能会使您在新的较大查询中的估计更糟,这意味着性能较差
- 如果您多次使用该表,您可以考虑在临时表上放置索引和/或主键,以便为这些查询对其进行排序。使用在和其他表联接时有用的列
临时表(例如,在Temp_DB中(通常非常快。与普通表相比,它们还有一些优势,因为它们需要更少的事务日志记录。如果临时表的创建真的会对时间产生如此大的影响,我会感到惊讶。
Pinal Dave做了一个非常好的快速视频,讲述了在存储过程中删除临时表与让它们自动删除是否有效果——简而言之,答案是"没有"。
更新:我刚刚在一台10年前的电脑上做了一个测试。
CREATE PROCEDURE _TestA AS BEGIN CREATE TABLE #a (a int); END;
GO
CREATE PROCEDURE _TestB AS BEGIN CREATE TABLE #a (a int); CREATE TABLE #b (a int); END;
GO
EXEC _TestA;
GO 1000
EXEC _TestB;
GO 1000
第一次花了4秒,第二次花了6秒。这表明创建临时表最多只需要几毫秒。