Sql-Server

隨著更多行被刪除,索引碎片增加

  • January 12, 2012

我有一個包含超過 1800 萬條記錄的表。我有一個每天從該表中清除數據的過程。索引碎片很低。

該表具有高事務吞吐量。它每秒儲存大約 3 到 5 條新記錄,因此我們知道清除該表的舊記錄需要快速。

刪除語句是這樣的:

Delete top 1000 
From MyTable 
Where CreationDate < 'Some Date'

理想情況下,我們會一直執行它,直到無法刪除更多行。

對於前 600 萬條記錄,刪除過程進展順利,但隨著時間的推移,刪除開始變慢,直到它影響訪問同一表的其他應用程序。此外,許多外鍵索引變得碎片化。

我的問題是:

  1. 刪除大量行會導致外鍵索引產生碎片嗎?(即索引依賴表)
  2. 刪除是不是因為外鍵索引碎片化而變慢了?(較慢的參考數據查找)
  3. 是否有一個平衡的策略可以保持刪除和外鍵索引的性能都很高?

我使用的是 SQL Server 2005 標準版。

$$ Update $$我在這裡包含了更多資訊實際的表名稱為“VehicleLocation”鍵列:

  • VehicleLocationKey(PK,char(36),不為空)
  • AgencyVehicleKey (FK, char(36), not null)
  • 分配鍵 (FK, char(36, null)
  • EmployeeKey (FK, char(36), null)

索引

  • VehicleLocation_AssignmentKey(非唯一、非集群)
  • VehicleLocation_CreationDate(非唯一、非集群)
  • VehicleLocation_MessageGenerationDate(非唯一,集群)
  • VehicleLocation_pk(唯一,非集群)

VehicleLocation 的對象依賴項(約 1050 萬行)

  • VehicleLocationAPC(~76000 行)
  • VehicleLocationFare (0 行)
  • VehicleLocationGF ( 0 行)
  • VehicleLocationInpt (0 行)
  • VehicleLocationOBD(約 15000 行)
  • VehicleLocationTP(約 830 萬行)

上述所有表的主鍵和 VehicleLocationKey (FK) 表都有索引。

此外,我們使用 GUID 作為主鍵(壞主意,但它是遺留的)。最重要的是,我看到 VehicleLocationTP 索引的碎片率為 96%,非常高。

這不是碎片化。

當然會產生碎片,但刪除只會創建剩餘頁面的“孤島”,這比 GUID/集群鍵 INSERT 碎片更不邪惡。

如果您的 PK 是一個 IDENTITY,那麼CreationDate應該粗略地跟踪它,以便您實際上刪除了連續行的塊。

  1. 你有索引嗎CreationDate
  2. 你有刪除級聯嗎?
  3. TOP 1000 是單筆交易嗎?

對於第 3 點,在事務中執行循環是沒有意義的:是這樣嗎?

在某些時候,如果您刪除了足夠多的行,可能需要更新統計資訊,但我認為不是這樣。

其他選項:

  • 為什麼不使用帶有 EXECUTE AS OWNER 的儲存過程包裝的 TRUNCATE TABLE
  • 使用同義詞進行窮人的分區

引用自:https://dba.stackexchange.com/questions/10534