我有一個SQL 2005表,裏面有數以百萬計的行,整天都在用戶點擊。該表由20個左右的具有外鍵約束的其他表引用。我需要定期執行的操作是刪除此表中「活動」字段設置爲false的所有記錄,並且在引用父記錄的任何子表中沒有其他記錄。這樣做最有效的方法是什麼?儘量一次刪除每一個,並讓它在違反約束的情況下導致SQL錯誤?此外,它不是一個禁用約束的選項,並且我無法在父表上鎖定任何大量時間。刪除所有沒有外鍵約束的記錄
4
A
回答
7
如果這是不太可能,不活動的行構成沒有鏈接會被連接在一起,可以運行(甚至是動態創建的基礎上,外鍵的元數據):
SELECT k.*
FROM k WITH(NOLOCK)
WHERE k.Active = 0
AND NOT EXISTS (SELECT * FROM f_1 WITH(NOLOCK) WHERE f_1.fk = k.pk)
AND NOT EXISTS (SELECT * FROM f_2 WITH(NOLOCK) WHERE f_2.fk = k.pk)
...
AND NOT EXISTS (SELECT * FROM f_n WITH(NOLOCK) WHERE f_n.fk = k.pk)
而且你可以把它變成一個DELETE很容易地。但是大的刪除可能會佔用很多鎖,因此您可能希望將其放入表中,然後批量刪除 - 除非記錄已鏈接,否則批處理不應失敗。
爲了提高效率,您確實需要在相關表格中的FK列上有索引。
你也可以用左連接來做到這一點,但是你(有時)必須用DISTINCT或GROUP BY去重載,執行計劃通常並不是更好,並且不利於代碼生成:
SELECT k.*
FROM k WITH(NOLOCK)
LEFT JOIN f_1 WITH(NOLOCK) ON f_1.fk = k.pk
LEFT JOIN f_2 WITH(NOLOCK) ON f_2.fk = k.pk
...
LEFT JOIN f_n WITH(NOLOCK) ON f_n.fk = k.pk
WHERE k.Active = 0
AND f_1.fk IS NULL
AND f_2.fk IS NULL
...
AND f_n.fk IS NULL
0
對你的問題有點困惑。但是你可以從你的主表執行一個LeftOuterJoin,到一個應該有一個外鍵的表。然後,您可以使用Where語句來檢查連接表內的空值。
入住這裏外連接:http://en.wikipedia.org/wiki/Join_%28SQL%29#Left_outer_join
你也應該寫觸發條件做這一切爲你當一條記錄被刪除或設置爲false等
3
讓我們我們有父表的名稱Parent
和它在任何類型和類型bit
的「Active
」字段的「id
」字段。我們還有第二個Child
表,其中有他自己的「id
」字段和「fk
」字段,它是對Parent
表的「id
」字段的引用。然後你可以使用如下語句:
DELETE Parent
FROM Parent AS p LEFT OUTER JOIN Child AS c ON p.id=c.fk
WHERE c.id IS NULL AND p.Active=0
相關問題
- 1. 如何刪除所有表中的所有外鍵約束?
- 2. 刪除具有外鍵約束的行
- 3. 程序刪除外鍵約束和刪除沒有行動
- 4. 用於刪除所有外鍵約束和唯一約束的TSql腳本?
- 5. mysql的刪除所有記錄刪除外鍵
- 6. 刪除SQL行忽略所有外鍵和約束
- 7. 使用外鍵約束刪除多個表中的記錄
- 8. 如何將具有外鍵約束的記錄刪除到另一個表中?
- 9. C#WPF:刪除具有外鍵約束(Access數據庫)的記錄
- 10. 如何使用外鍵約束刪除記錄?
- 11. 在Entity Framework中,如何使用外鍵約束刪除記錄?
- 12. 由於外鍵約束,無法刪除現有的唯一鍵
- 13. 刪除除一個重複記錄以外的所有記錄
- 14. 刪除複製表的外鍵約束
- 15. 參照表沒有外鍵約束
- 16. 從具有外鍵約束的MySQL表中刪除
- 17. 從兩個具有外鍵約束的表中刪除
- 18. 使用帶有外鍵約束的JPA刪除對象
- 19. SQL和外鍵約束刪除
- 20. MySQL外鍵約束,級聯刪除
- 21. 不能刪除外鍵約束
- 22. 刪除Mysql表列與外鍵約束
- 23. 使用外鍵約束刪除行
- 24. mysql刪除和外鍵約束
- 25. 如何刪除外鍵約束
- 26. 自引用外鍵約束和刪除
- 27. 無法刪除外鍵約束
- 28. VHDL記錄沒有完全約束
- 29. 刪除所有舊記錄
- 30. 如何在Sql Server 2000的表中刪除所有外鍵約束?
觸發的想法是好的,但不能在這種情況下使用,因爲成千上萬的記錄得到一次定期設置爲false,將觸發對錶將導致每個停用批次的每個記錄都有單獨的事務。 – 2010-05-07 00:09:09
@Rodney Burton觸發器在每個語句中調用(即單個UPDATE批處理),而不是每行受影響,但它並不總是一個好主意。 – 2010-05-07 00:22:54