[英]improve sql delete performance and reduce log file and tempDB size?
我有一個龐大的數據庫,它每天處理電子郵件流量。 在系統中,它每天需要刪除一些舊電子郵件:
Delete from EmailList(nolock)
WHERE EmailId IN (
SELECT EmailId
FROM Emails
WHERE EmailDate < DATEADD([days], -60, GETDATE())
)
它可以工作,但是問題是:這需要很長時間才能完成,因此日志文件變得非常大。 日志文件大小每天增加超過100GB。
我想我們可以將其更改為
Delete from EmailList(nolock)
WHERE EXISTS (
SELECT EmailId
FROM Emails
WHERE (Emails.EmailId = EmailList.EmailId) AND
(EmailDate < DATEADD([days], -60, GETDATE()))
)
但是除此之外,我們還有什么可以改善性能的。 最重要的是,減少日志文件的大小?
我見過
GetDate()-60
樣式語法比
DATEADD([days], -60, GETDATE()))
特別是在日期列上有索引的情況下。 我和一些DBA同事花了很多時間試圖理解為什么它會表現更好,但是結果卻出在布丁上。
考慮到我認為必須刪除的記錄量,您可能要考慮的另一件事是將刪除內容分批處理,例如1000或10000條記錄。 這可能會加快刪除過程。
[編輯]:
關於@TomTom的評論:如果您有可用的SQL Server Enterprise版本,則應使用Table Partitioning 。
如果不是這種情況,我的原始帖子可能會有所幫助:
[原帖]
刪除大量數據始終很困難。 我遇到了同樣的問題,並采取了以下解決方案:
根據您的要求,這可能不起作用,但是也許您可以從中獲得一些想法。
代替使用1個表,使用具有相同架構的2個表 。 創建一個指向“ 2個表的活動表(活動方式,這是您當前寫入的表)”的同義詞(我假設您正在使用MS SQL Server)。對該應用程序中的插入使用此同義詞,或者無需使用同義詞,應用程序只需在寫入表的每x天更改一次表即可。
每隔x天,您都可以截斷舊的/不活動的表 ,然后重新創建同義詞以定位被刪節的表(如果使用synonnym解決方案),因此可以有效地每次對數據進行分區。
您必須同步活動表的切換。 通過為應用程序使用共享的App-lock和更改同義詞時的Exclusive Applock(===在切換過程中阻止了編寫應用程序),我完全實現了自動化。
如果不能選擇更改應用程序的代碼,請考慮使用相同的原理,但是可以使用代替觸發器的視圖來創建同義詞(插入操作將插入到“活動”分區中),而不是編寫同義詞。 觸發代碼將需要使用如上所述的Applock之類的方法進行同步(以便在切換過程中進行寫操作)。
我的解決方案要復雜得多,所以我目前無法在此處發布代碼,但是對於高負載應用程序,它可以正常工作,並且切換/清理過程是完全自動化的。
您是否嘗試過按日期進行分區,那么就可以刪除不再感興趣的日期的表版本。 給定一個“休”數據庫,您肯定會運行SQL Server企業版(畢竟,休大於很大),並且該數據庫具有表分區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.