我有一个带表的 Azure SQL 服务器(标准层,S3)。我有一个需要很长时间才能执行的特定查询:
DELETE FROM MyTable WHERE ID=@ID
此表有 150K 行。删除查询需要 +-10 分钟。
我试着去理解为什么。首先检查在 SELECT 查询中定位此行的速度有多快。我跑:
SELECT * FROM MyTable WHERE ID=@ID
结果:不到 2 秒。
我在 this thread 中读到过这个问题.我选择了答案并从中提取了一个检查列表。在里面查看我的答案。
list :
- 删除大量记录 - 此查询恰好删除 1 行。
- 许多索引 -
MyTable
有:1 个 PK、1 个 FK、4 个索引,除此之外别无其他。所以我相信这不是问题所在。 - 缺少子表中外键的索引 - 我唯一的 FK 在另一个表上也有 INDEX。
- 触发器 - 没有触发器。
- 级联删除(您删除的那 10 个父记录可能意味着数百万个子记录被删除)- 我试图删除其他表中引用的行。因此,级联删除不应删除其他表上的任何内容。
- 要检查许多外键 - 不确定是什么意思。我只有一个 FK 指向非常小的表(<10 行 + 索引)。
- 事务日志需要增长 - 如何检查?
- 死锁和阻塞 - 如何检查?
我的直觉是,它以某种方式依赖于引用该表的其他表(MyTable
对它们而言是 FK)。由于我有+-15个表,我不知道如何定位问题。
补充观察:我发现了一些有趣的东西。如果你一个接一个地运行删除,第一次调用会花费很多时间(如上所述),第二次调用更快等等。如果您多次运行此查询,它会变得非常快(<3 秒 - 这很棒)。几个小时后 - 它又变慢了。
问题:
- 还有什么要检查的?
- 是否可以运行
DELETE
查询并分析它?假设table2
具有到MyTable
的 FK,并且搜索行@ID
需要花费大量时间。也许我可以有一个工具说:“99% 的执行时间花在table2
上?” - 欢迎任何其他提示!
谢谢!
最佳答案
问题解决了。
为了做到这一点,我做了:
- 手动检查了数据库中的所有表并确认它们有 INDEX over FK 到
MyTable
。我发现 4 个表缺少索引。这些表非常小(<1K 行)。不确定效果如何。 - 我有一个执行了很多次的 SP。此 SP 正在运行一个事务,该事务锁定了其中一个表,FK 为
MyTable
。我取下了锁。 Agian,不确定它的效果如何,因为我上面提到的 senario 是该行在其他表上实际上没有任何 FK 行。
但是,现在它就像一个魅力!执行时间 <1 秒!
关于sql-server - SQL DELETE 花费太多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52056107/