【问题标题】:SQL DELETE is taking too much timeSQL DELETE 花费了太多时间
【发布时间】:2018-08-28 10:52:17
【问题描述】:

我有一个带有表的 Azure SQL 服务器(标准层,S3)。我有一个需要很长时间才能执行的特定查询:

DELETE FROM MyTable WHERE ID=@ID

此表有 150K 行。删除查询需要 +-10 分钟。

我试图理解为什么。首先检查的是在 SELECT 查询中定位该行的速度。我跑:

SELECT * FROM MyTable WHERE ID=@ID

结果:不到 2 秒。

我在this thread 中了解了这个问题。我选择了答案并从中提取了一个清单。在里面查看我的答案。

清单:

  • 删除大量记录 -​​ 此查询仅删除 1 行。
  • 许多索引 - MyTable 有:1 个 PK、1 个 FK、4 个索引,仅此而已。所以我相信这不是问题。
  • 子表中的外键索引缺失 - 我唯一的 FK 在另一张表上也有 INDEX。
  • 触发器 - 没有触发器。
  • 级联删除(您要删除的那十个父记录可能意味着数百万个子记录被删除)-我试图删除在其他表中引用的行。因此,级联删除不应删除其他表上的任何内容。
  • 要检查的许多外键 - 不确定是什么意思。我只有一个 FK 指向非常小的表(
  • 事务日志需要增长 - 如何查看?
  • 死锁和阻塞 - 如何检查?

我的直觉是,它在某种程度上取决于引用该表的其他表(MyTable 对他们来说是 FK)。由于我有+-15个表,不知道如何定位问题。

补充观察:我发现了一些有趣的东西。如果您一个接一个地运行删除,第一次调用会花费很多时间(如上所述),第二次调用会更快,依此类推。如果您多次运行此查询,它会变得非常快(

问题:

  1. 还有什么要检查的?
  2. 这是否可以运行DELETE 查询并对其进行分析?假设table2MyTable 有一个FK,并且搜索行@ID 需要花费大量时间。也许我可以有一个工具说:“99% 的执行时间花在table2 上?”
  3. 欢迎任何其他提示!

谢谢!

【问题讨论】:

  • 即使您的表没有其他实际引用,如果存在此类约束,SQL Server 在删除而不是选择表中的每条记录时可能需要做更多的工作。跨度>
  • A) 检查索引的碎片 B) 运行删除语句,然后运行 ​​SP_Who2 活动,检查 CPU 和 IO。 C) 你的 .mdf 和 .ldf 文件有多大
  • 虽然您的问题可能有程序化解决方案,但如果您在 DBA StackExchange Site 上提出问题,我认为您可能有更大的机会找到问题的原因和解决方案
  • 当我试图从包含约 100 万行的表中删除时,我遇到了一个案例,但它花了很长时间。使用 select * 查询行很快,但删除速度非常慢。然后我意识到另一个表有一个外键,它有 20 亿(!)行。当然,FK 列没有被索引。解决方案:删除 FK,删除行,重新创建 FK。重新创建 FK 仍然需要一些时间,但速度要快得多。
  • 将您的实际执行计划上传至brentozar.com/pastetheplan,并将链接添加到您的问题中。后续删除比第一次删除要快得多的事实表明完全扫描,其中数据在第一次运行时不会被缓存。

标签: sql-server azure-sql-database sql-server-profiler azure-sql-server


【解决方案1】:

解决了这个问题。

为了做到这一点,我做了:

  1. 手动检查数据库中的所有表,并确认它们具有通过 FK 到 MyTable 的 INDEX。我发现了 4 个缺少索引的表。这些表非常小(
  2. 我有一个执行了很多次的 SP。此 SP 正在使用 FK 到 MyTable 的其中一个表上运行带有锁定的事务。我卸下了锁。 Agian,不确定它有多有效,因为我上面提到的场景是该行在其他表上实际上没有任何 FK 行。

但是,现在它就像一个魅力!执行时间

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 2017-02-15
    • 2020-07-23
    • 2013-07-11
    • 2014-01-13
    • 1970-01-01
    相关资源
    最近更新 更多