【问题标题】:SQL Server 2008R2 query stallingSQL Server 2008R2 查询停止
【发布时间】:2017-08-04 06:34:48
【问题描述】:

我有 2 个表,TableA 和 TableB

TableA 包含近 3,000,000 条记录 TableB 包含大约 10,000 条记录

我想删除 TableA 中匹配某个参数的条目。对于较小的表,此查询已正常运行,但在 VB.Net 中运行时出现超时异常

delete FROM TableA WHERE (((TableA.ID) In (SELECT [TableB].ID FROM TableB)) AND ((TableA.EVDATE)='20170720'));

为了看看发生了什么,我在 SSMS 中将其更改为 SELECT * FROM... 并且在 5 分钟没有结果时,我停止了它...

为什么会停止?有没有更好的方法?

我认为这更容易阅读:

delete FROM TableA  WHERE TableA.EVDATE='20170720' and  TableA.ID In 
(SELECT [TableB].ID FROM TableB);

【问题讨论】:

  • 仅在需要时使用括号。不必要的括号会使代码笨拙难懂
  • TableA.IDTableA.EVDATE 上创建索引将有助于查询运行得更快..
  • 另外加入而不是使用IN 可能会更快,您需要尝试一下。
  • 我创建了一个非聚集索引,这似乎大大提高了性能。 Create NonClustered Index IX_IndexName On TableA (ID Asc, EVDATE Asc);
  • @Tym 我更新了您上面的查询,以便更好地阅读。

标签: sql-server vb.net sql-server-2008-r2


【解决方案1】:

您需要将已删除记录的数量拆分为多个调用

例子:

单独删除每 1000 行

DELETE FROM TableA 
WHERE TableA.ID IN (SELECT TOP (1000) ID FROM TableA)

您可以对它们进行循环并检查 @@ROWS_COUNT 如果为 0 则所有行都已删除且无需召回,或者如果 @@ROWS_COUNT

大查询需要大量事务日志资源(DatabaseName_Log.mdb 文件而不是数据库文件),当您拆分时,您将受益于更少的资源和更低的日志,这使得每删除较少数量的记录就可以更快地执行

【讨论】:

  • 这没有考虑到AND TableA.EVDATE='20170720'的需要。我尝试了您的建议,但在 00:02:00 它仍在运行。
  • 这是错误的。每次子查询可以返回相同的1000条已经被删除的记录!!
  • 我认为创建一个存储过程来增加顶部(1000)会更好。或者专门删除数据。
  • 客户端必须完成所有工作,因此没有存储过程。
  • 我说“对它们进行循环”,他可以在 C# 上循环,这更好,因为存储过程仍然是相同的问题,存储过程更快,但在这种情况下,我们将遇到相同的 DataBase_Log 问题,因为使用存储过程作为完全删除查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 2021-05-02
  • 2018-04-03
相关资源
最近更新 更多