SQL table 中删除记录的速度

Speed in deleting records in SQL table

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

这里是代码段:

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 服务器性能问题。

我想把上面的代码改成

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

简短答案

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

例如,我在下面注释掉了您不需要的内容,并在 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

如果在该存储过程中,您

  • 创建临时文件table
  • 将values/data插入其中
  • 通过 DELETE FROM #Updates
  • 删除其中的所有内容
  • 向其中插入新值

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

Explanation/longer 答案:

暂时table是

  • 仅在当前 session/scope 和
  • 期间可用
  • 存储过程完成时删除

如果您同时 运行 存储过程两次,每个都会创建、使用,然后删除自己的临时 table - 它们将无法被彼此访问。

在提高性能方面

  • 如果您只使用 table 一次(例如,您创建它,插入它,在连接中使用它,然后完成它),您可以改为将 SQL 移动到成为您正在使用的连接的一部分(例如,绕过创建临时 table 的需要)。这避免了创建临时 table 的成本,但可能会使您在新的更大查询中的估计更糟,这意味着性能不佳
  • 如果您多次使用 table,您可以考虑将索引 and/or 作为临时 table 的主键,以便为这些查询排序。使用在与其他 table 的连接中有用的列。

临时 tables(例如,在 Temp_DB 中)通常非常快。它们也比普通的 tables 有一些优势,因为它们需要更少的事务日志记录。如果创建临时 table 真的会影响时间,我会感到惊讶。

Pinal Dave 制作了一个非常不错的快速视频,介绍了 Dropping temporary tables in a stored procedure 与让它们自动删除是否有效果 - 简而言之,答案是 'no'。

更新:我刚刚在一台大约有 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秒。这表明创建临时文件 table 最多只需要几毫秒。