2009-12-07 612 views
25

我在表中有一行。該行在其他幾個具有數百萬行的表中引用了ID列。用於刪除行的SQL語句總是超時。從我的設計中,我知道我希望刪除的行從未在其他地方引用。因此,我希望SQL忽略必須檢查所有其他表以查找該行的外鍵引用並立即刪除該行。有沒有在SQL 2008中做到這一點的快速方法? 也許沿線的東西:刪除SQL行忽略所有外鍵和約束

DELETE FROM myTable where myTable.ID = 6850 IGNORE CONSTRAINTS 

或沿着這些線的東西。

+3

您是否考慮過在相關表格的關鍵參考列中添加索引?如果不存在,這將允許SQL快速確定是否有其他行引用了您嘗試刪除的行 - 並且可能會給您帶來顯着的性能提升...... – 2009-12-08 14:18:58

+0

我可以提出另一種方法。在我的系統中,大多數(數百個)表格指向dbo.Company.Id。即使刪除一個沒有引用的空公司,也會導致DB以十億行檢查FK完整性。解決方案:只需使用邏輯刪除。 – jean 2016-07-27 16:36:24

回答

30

您可以將該表/列上的約束設置爲不臨時檢查,然後重新啓用約束。一般的形式是:

ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName 

然後重新啓用所有的約束與

ALTER TABLE TableName CHECK CONSTRAINT ConstraintName 

我認爲這將是暫時的,但?你顯然不想一直這樣做。

1

在有外鍵指向這一個,使用所有表:

ALTER TABLE MyOtherTable NOCHECK CONSTRAINT fk_name 
17

是的,只需運行

DELETE FROM myTable where myTable.ID = 6850 

並讓發動機驗證CONS訓練

如果您試圖成爲'聰明'並禁用約束,您將付出巨大的代價:啓用約束必須驗證每行而不是您剛剛刪除的約束。有內部標誌SQL一直知道一個約束是否'可信'。您'優化'會導致將這些標誌更改爲'false'(意味着SQL不再信任這些約束),或者必須從頭開始重新驗證它們。

請參閱Guidelines for Disabling Indexes and ConstraintsNon-trusted constraints and performance

除非您做了一些固體測量結果,證明DELETE操作的約束驗證是性能瓶頸,讓引擎完成其工作。

+1

只是有一些實際的數字:從12M表中刪除10M記錄實際上是2分鐘慢1個臨時停用約束比它激活(12:18比10:28) - SQL-Server – Remco 2016-05-20 10:08:24

+1

在某些情況下,就像在DB重新創建一個域表一樣,要求並確定禁用FK檢查,因爲如果你發現有人以某種方式添加了一個帶有不正確代碼值的查找項目,那麼你必須刪除該項目並用正確的代碼和文本值。 – ProfK 2017-04-14 14:30:01

7

請勿在任何情況下禁用約束。這是一個非常愚蠢的做法。如果你這樣做,你不能保持數據的完整性。數據完整性是數據庫的首要考慮因素,因爲沒有它,您什麼​​都沒有。

正確的方法是在嘗試刪除父記錄之前從子表中刪除。您可能會超時,因爲您已設置級聯delte,這是大型數據庫中另一個不好的做法。

+6

在某些情況下,當您確實知道自己在做什麼並確保在交易結束時滿足所有約束條件時,它可能非常有用。例如,SqlBulkCopy默認會忽略約束,這在您思考時很有意義。 – chris 2013-02-11 14:30:57

+1

@chris,那裏的關鍵詞真的知道你在做什麼。通常這些人不會問如何禁用互聯網上的限制。 – HLGEM 2013-02-11 15:02:28

1

我想從兩個表中刪除所有記錄,因爲它全部是測試數據。我使用SSMS GUI暫時禁用FK約束,然後我在兩個表上運行了DELETE查詢,最後我重新啓用了FK約束。

要禁用FK約束:

  1. 展開數據庫對象[1]
  2. 擴大相關表的對象[2]
  3. 展開 '鍵' 文件夾
  4. 右鍵點擊外鍵
  5. 選擇'修改'選項
  6. 將'強制外鍵約束'選項更改爲'否'
  7. 關閉「外鍵關係」窗口
  8. 關閉表設計器選項卡
  9. 當系統提示確認保存
  10. 運行必要的修改,刪除查詢
  11. 重新啓用外鍵約束你只是禁用它以同樣的方式。

[1]在「對象資源管理器」窗格中,可以通過「查看」菜單選項,或按F8鍵來訪問

[2]如果你不知道這表是一個依賴,可以通過右鍵單擊相關表格並選擇「查看依賴項」選項來進行檢查。

+0

我發現刪除對象資源管理器中的表更容易,並讓批量重新創建它們(對於因FK約束而無法刪除的表再次運行刪除操作)。 – appl3r 2017-09-20 10:00:03

1

我知道這是一箇舊的線程,但當我的行刪除被外鍵約束阻止時,我在這裏登陸。就我而言,我的表格設計允許在約束列中使用「NULL」值。在要刪除的行中,我將受約束的列值更改爲「NULL」(不違反外鍵約束),然後刪除所有行。