我在表中有一行。该行在其他几个具有数百万行的表中引用了ID列。用于删除行的SQL语句总是超时。从我的设计中,我知道我希望删除的行从未在其他地方引用。因此,我希望SQL忽略必须检查所有其他表以查找该行的外键引用并立即删除该行。有没有在SQL 2008中做到这一点的快速方法? 也许沿线的东西:删除SQL行忽略所有外键和约束
DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS
或沿着这些线的东西。
我在表中有一行。该行在其他几个具有数百万行的表中引用了ID列。用于删除行的SQL语句总是超时。从我的设计中,我知道我希望删除的行从未在其他地方引用。因此,我希望SQL忽略必须检查所有其他表以查找该行的外键引用并立即删除该行。有没有在SQL 2008中做到这一点的快速方法? 也许沿线的东西:删除SQL行忽略所有外键和约束
DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS
或沿着这些线的东西。
您可以将该表/列上的约束设置为不临时检查,然后重新启用约束。一般的形式是:
ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName
然后重新启用所有的约束与
ALTER TABLE TableName CHECK CONSTRAINT ConstraintName
我认为这将是暂时的,但?你显然不想一直这样做。
在有外键指向这一个,使用所有表:
ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name
是的,只需运行
DELETE FROM myTable where myTable.ID = 6850
并让发动机验证CONS训练。
如果您试图成为'聪明'并禁用约束,您将付出巨大的代价:启用约束必须验证每行而不是您刚刚删除的约束。有内部标志SQL一直知道一个约束是否'可信'。您'优化'会导致将这些标志更改为'false'(意味着SQL不再信任这些约束),或者必须从头开始重新验证它们。
请参阅Guidelines for Disabling Indexes and Constraints和Non-trusted constraints and performance。
除非您做了一些固体测量结果,证明DELETE操作的约束验证是性能瓶颈,让引擎完成其工作。
请勿在任何情况下禁用约束。这是一个非常愚蠢的做法。如果你这样做,你不能保持数据的完整性。数据完整性是数据库的首要考虑因素,因为没有它,您什么都没有。
正确的方法是在尝试删除父记录之前从子表中删除。您可能会超时,因为您已设置级联delte,这是大型数据库中另一个不好的做法。
我想从两个表中删除所有记录,因为它全部是测试数据。我使用SSMS GUI暂时禁用FK约束,然后我在两个表上运行了DELETE查询,最后我重新启用了FK约束。
要禁用FK约束:
[1]在“对象资源管理器”窗格中,可以通过“查看”菜单选项,或按F8键来访问
[2]如果你不知道这表是一个依赖,可以通过右键单击相关表格并选择“查看依赖项”选项来进行检查。
我发现删除对象资源管理器中的表更容易,并让批量重新创建它们(对于因FK约束而无法删除的表再次运行删除操作)。 – appl3r 2017-09-20 10:00:03
我知道这是一个旧的线程,但当我的行删除被外键约束阻止时,我在这里登陆。就我而言,我的表格设计允许在约束列中使用“NULL”值。在要删除的行中,我将受约束的列值更改为“NULL”(不违反外键约束),然后删除所有行。
您是否考虑过在相关表格的关键参考列中添加索引?如果不存在,这将允许SQL快速确定是否有其他行引用了您尝试删除的行 - 并且可能会给您带来显着的性能提升...... – 2009-12-08 14:18:58
我可以提出另一种方法。在我的系统中,大多数(数百个)表格指向dbo.Company.Id。即使删除一个没有引用的空公司,也会导致DB以十亿行检查FK完整性。解决方案:只需使用逻辑删除。 – jean 2016-07-27 16:36:24