【问题标题】:Speed in deleting records in SQL tableSQL表中删除记录的速度
【发布时间】:2021-02-25 00:30:44
【问题描述】:

我有一个临时表,用于存储过程中的中间计算。

这里是代码段:

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 的性能。如果有更好的方法,也请告诉我。

【问题讨论】:

  • 不要DELETE,它会一样慢 - 如果有的话,只需TRUNCATE TABLE #Updates

标签: sql create-table drop-table delete-record


【解决方案1】:

答案的简短版本

  • 取消对临时表是否存在的检查 - 这些仅在开发和手动执行部分代码时有用
  • 除非你从临时表中删除然后添加新数据,否则只要在存储过程完成时自然删除临时表即可
  • 还要考虑主键和/或索引是否有帮助

例如,我在下面注释掉了你不需要的东西,并在 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 #Updates 删除其中的所有内容
  • 向其中插入新值

然后使用TRUNCATE TABLE #Updates 会比从中删除快一点。

解释/更长的答案:

临时表是

  • 仅在当前会话/范围内可用,并且
  • 在存储过程完成时删除

如果您同时运行存储过程两次,则每个都将创建、使用、然后删除自己的临时表 - 并且它们将无法相互访问。

在提高性能方面

  • 如果您只使用该表一次(例如,您创建它、插入它、在连接中使用它,然后完成它),您可以将 SQL 移动到您正在使用的连接中(例如,绕过创建临时表的需要)。这避免了创建临时表的成本,但可能会使您在新的更大查询中的估计更差,这意味着性能不佳
  • 如果您多次使用该表,您可以考虑在临时表上放置索引和/或主键,以便对这些查询进行排序。使用在与其他表连接时有用的列。

临时表(例如,在 Temp_DB 中)通常非常快。与普通表相比,它们还具有一些优势,因为它们需要的事务日志记录要少得多。如果临时表的创建真的对时间有那么大的影响,我会感到惊讶。

Pinal Dave 制作了一个非常棒的快速视频,说明 Dropping temporary tables in a stored procedure 是否会产生影响,而只是让它们被自动删除 - 简而言之,答案是否定的。

更新:我刚刚在一台大约 10 岁的 OK-ish 计算机上进行了测试。

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 秒。这表明创建临时表最多只需要几毫秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    相关资源
    最近更新 更多