从表Transact-SQL中删除行数

时间:2012-02-09 06:04:23

标签: sql-server sql-server-2008 tsql

一般情况下,有必要从表Nodes中删除大约110K行,但是他们的id没有明确声明,而是从另一个表中提供。

DECLARE @gh Table(id int);
INSERT INTO @gh (id) SELECT node_id FROM Relations;
DELETE FROM Nodes WHERE id NOT IN (SELECT DISTINCT id FROM @gh)

选择(SELECT DISTINCT id FROM @gh)包含大约20K行,由于超时过期,服务器无法删除它们。有什么其他方法可以做到吗?

4 个答案:

答案 0 :(得分:3)

如果你保持20k的130k,我会采用不同的方式

SELECT N.* 
  INTO #NodesTemp 
FROM  
  Relations R JOIN Nodes N ON R.id = N.id;

TRUNCATE TABLE Nodes;

INSERT Nodes SELECT * FROM #NodesTemp;

DROP TABLE #NodesTemp;

编辑:

  • 您是否在节点上有DELETE触发器?
  • 您是否有需要检查的节点的外键?

答案 1 :(得分:1)

这样的事可能会有所帮助。它将删除没有相关Relation条目的所有节点。外连接应该比使用子查询的“not in”子句快得多。

delete n
from Nodes n left outer join Relations r on n.id = r.node_id
where r.node_id is null

答案 2 :(得分:1)

您可以尝试通过向DELETE添加TOP子句来批量删除节点而不是一次删除所有节点:

WHILE EXISTS(SELECT * FROM Nodes WHERE id NOT IN (SELECT DISTINCT id FROM @gh))
DELETE TOP (100) Nodes
WHERE id NOT IN (SELECT DISTINCT id FROM @gh)

答案 3 :(得分:0)

您不需要DINSTINCT。它为delete语句增加了不必要的开销。

其次,你为什么要使用临时表?您是否尝试将这两个语句合并为一个?:

DELETE 
FROM Nodes 
WHERE id NOT IN 
      (SELECT node_id FROM Relations)

或删除较小块中的行,如@Serguei建议:

SELECT 1

WHILE @@ROWCOUNT > 0
BEGIN
    DELETE TOP (1000)
    FROM Nodes 
    WHERE id NOT IN 
          (SELECT node_id FROM Relations)
END