car*_*reo 0 foreign-key sql-server delete sql-server-2016
在我正在处理的数据库中,有一个名为 的表,persons大约有一百万行,并且来自其他表(有些有数百万行)的 60 个 FK (FK) 约束指向它。
如果我从 中删除一行persons,则需要很多分钟,这不会是问题,但它也会使表保持锁定,从而阻止数据库的所有进程。过去,这曾导致用户报告系统宕机。
当然,如果我为所有的FK添加支持索引的话,情况会大大改善(目前60张表中只有20张有)。但是这些FK很多都是针对诸如 之类的列modified_by,因此所有索引都没有其他目的,并且会在日常操作中降低系统的性能,只有在特殊情况下才能获得改进。
在运行 DELETE 之前,我已经确保所有引用行都已被删除或更新。我手动执行此操作,因为我强烈反对使用 CASCADE。
我没有考虑软删除,因为否则我将不得不更改读取表persons以跳过已删除行的所有软件。
有没有办法(可能是暂时的)更改表的锁定机制persons,以便即使 DELETE 需要一个小时,也不会影响并发进程?
禁用 FK 可能是一种可能。风险在于,当我删除该行时,其他人会造成不一致,然后我无法重新启用 FK。
要删除的行:通常一次删除一行。手动操作或计划操作。
有趣的一点:我没有立即检查执行计划,但显然,除了引用表的 PK 上的 7 例“聚集索引扫描(Clustered)”之外,几乎所有操作的成本都是 0%;其中一种费用为 57%,另一种费用为 1% 至 16%。我仍然不明白为什么它应该扫描聚集索引。
如果我为所有FK添加支持索引,情况会大大改善(目前60个表中只有20个有)
您应该始终对用作外键或其他键的字段进行索引。这为数据库在分析如何执行查询时提供了更多选择,并且添加它们实际上可能会提高应用程序的整体性能。
其中许多 FK 用于诸如“修改者”之类的列,因此所有索引都没有其他目的
与行星数据库上的[几乎]所有内容一样,这是一种妥协。
在这里,您要平衡数据完整性 - 确定谁更改了某些内容 - 与速度 - 没有那些会减慢插入速度的额外索引。如果您不知道(确定)更改这些记录的用户,这真的很重要吗?如果没有,你就没事了。如果它确实很重要 - 在很多情况下,它确实非常重要 - 那么你就会陷入索引的开销。
在运行 DELETE 之前,我已经确保所有引用记录已被删除......
FK 就位后,您无论如何都无法删除它们,因此此活动的值值得怀疑。
问题确实应该是,为什么删除需要一个小时?
如果您只删除一百万行表中的一条记录,并且表中没有 FK 返回到该表的行,那么花费的时间是什么?它实际上应该是瞬时的。
缓慢的查询,甚至删除,通常是由于缺少索引引起的 - 您是否根据记录的主键字段执行删除?或者[未索引]字段的其他组合?
| 归档时间: |
|
| 查看次数: |
1691 次 |
| 最近记录: |