【发布时间】: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个表,不知道如何定位问题。
补充观察:我发现了一些有趣的东西。如果您一个接一个地运行删除,第一次调用会花费很多时间(如上所述),第二次调用会更快,依此类推。如果您多次运行此查询,它会变得非常快(
问题:
- 还有什么要检查的?
- 这是否可以运行
DELETE查询并对其进行分析?假设table2与MyTable有一个FK,并且搜索行@ID需要花费大量时间。也许我可以有一个工具说:“99% 的执行时间花在table2上?” - 欢迎任何其他提示!
谢谢!
【问题讨论】:
-
即使您的表没有其他实际引用,如果存在此类约束,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