我在表中有一行。該行在其他幾個具有數百萬行的表中引用了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