2008-11-12 72 views
6

每天晚上我都需要修剪一張表格,只包含最新的20,000條記錄。我可以使用子查詢:如何刪除MS SQL 2005中最新的20,000條記錄?

delete from table WHERE id NOT IN (select TOP 20000 ID from table ORDER BY date_added DESC) 

但這似乎效率低下,尤其是如果我們以後決定保留50,000條記錄。我使用的SQL 2005,並認爲我可以使用ROW_NUMBER()OVER以某種方式做到這一點?訂購它們並刪除所有ROW_NUMBER大於20,000的商品?但我無法實現它的工作。子查詢是我最好的選擇還是有更好的方法?

回答

7

如果它只是似乎低效率,我會確保它是低效的,然後我開始吠叫錯誤的樹。

衡量時間,cpu使用情況,磁盤I/O等,看看它的表現如何。我想你會發現它比你想象的要好。

+0

你是對的,它唯一的服用3秒清除表約50,000記錄在裏面。我認爲IN()子句非常低效,但也許就是當你實際傳入一個文本ID列表時。謝謝您的幫助。 – 2008-11-12 22:37:34

+0

是的,一個包含20,000個以逗號分隔的ID的IN()子句可能效率很低。不過,我敢打賭它仍然會在10-15秒內執行。 – MusiGenesis 2008-11-12 22:40:14

+0

這就是,如果它同意甚至解析一個字符串,當然很長。 – MusiGenesis 2008-11-12 22:40:50

0

當然,這是包裝進程序和使用兩個sql語句的首要情況 - 第一個選擇最新的ID並減去20,000,然後第二個刪除ID低於此的所有行。

然而,它的表面上聽起來就像你會用這種方法結束大量的碎片,這可能是創建新表的一個很好的參數,將最新的20,000條記錄插入它,刪除舊的並重命名新的。將表放在不同的數據庫中並創建主數據庫的視圖以方便訪問可能是值得的。我自己通常傾向於使用用於數據加載和審計的表執行此操作。

在不知道實際數據量和行爲的情況下很難分辨出來,但很可能是因爲全球範圍內您的低效率會比您使用的刪除方法更多。如果您每天只收集一千條或更少的記錄,那麼刪除可能與運行數據優化維護計劃相結合,但更多的是,我會考慮更激進的方法。

3

當然,你的里程會有所不同 - 這取決於你從這張桌子底部刮掉了多少實際記錄,但這裏有一個選擇。

注意:由於您有一個「Date_Added」字段,是否值得考慮只保留上次運行的日期時間並在where子句中使用該日期來過濾要刪除的記錄?現在,而不是20,000條記錄,允許在日誌中的天X個...只是一個想法...


- 讓我們希望保持到一個臨時的記錄。
- 您可以根據自己的意願對看門人進行分類。

select top 20000 * into #myTempTable from MyTable ORDER BY DateAdded DESC 

- 使用截斷不垃圾我們的日誌文件,並使用更少的資源SYS ...

truncate table MyTable 

- 把我們的 '保存' 記錄回折...
- 假定您不使用標識列 - 如果你是,你應該
- 指定的字段名稱,而不是使用「*」,並完成類似
- SET IDENTITY_INSERT MyTable的ON
- 插入MyTable的從#myTempTable
選擇場,場2,場3 - (我認爲這是正確的)

insert into MyTable select * from #myTempTable 

- 成爲一個好公民。

drop table #myTempTable 


希望它能幫助 -

3
DECLARE @limit INT 
SELECT @limit = min(id) FROM 
    (SELECT TOP 20000 id FROM your_table ORDER BY id DESC)x 
DELETE FROM your_table where id < @limit 

的一點是避免嵌套查詢,我可能會或可能不會進行優化(抱歉不是SQL大師。 )

0

你的問題意味着你正在調整從表中獲得更好的日間表現。你是否在日間查詢中獲得表掃描?沒有更好的索引是答案?或者你是否陷入了一種「糟糕的模式」?

或者確實有一些確實需要清除舊記錄的非常奇怪的情況? 20,000是難以置信的數字嗎?或者日期時間可以工作?然後,日期時間列上的索引將使裁剪更容易一些。

1

插入到20000臨時表中,然後刪除主表中的所有記錄然後再插入從臨時表中 20000記錄到主表..,

相關問題