如果桌子是堆,桌子會受益嗎
我有一個大約 1.500.000 行的日誌記錄表,主鍵是升序標識,聚集索引位於主鍵上。標識值是自動生成的 => 記錄總是添加到最後。平均行大小為 1570 字節。
由於經常添加新行,因此存在很多頁面拆分。沒有行得到更新/刪除,並且表上有一個非聚集索引,因此可以選擇行。由於頁面拆分,聚集索引的碎片率始終 > 65%。
我想知道我的表會受益於刪除聚集索引並使其成為堆表嗎?
這就是我的表 + 非聚集索引的樣子:
CREATE TABLE [dbo].[LogEntry]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Application] [varchar](20) NOT NULL, [EntityFullName] [varchar](80) NOT NULL, [Action] [int] NOT NULL, [UserName] [varchar](25) NOT NULL, [TimeStamp] [datetime] NOT NULL, [EntityId] [varchar](50) NOT NULL, [WhatChanged] [nvarchar](max) NULL, CONSTRAINT [PK_LogEntry] PRIMARY KEY CLUSTERED( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] CREATE NONCLUSTERED INDEX [ID_Application_Entity_FullName_TimeStamp] ON [dbo].[LogEntry] ( [Application] ASC, [EntityFullName] ASC, [TimeStamp] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY] GO
更新: 有人在我背後啟用了自動收縮=>這將是碎片的原因
這開始是一個評論/問題,但它很長,所以我把它移到了這裡:
我真的被這個問題拋出了。150 萬行並不是那麼大。身份背後的意義在於它在不斷增加。如果那是您的 CL,您不應該在頁面中間插入,當然不會經常導致您看到的碎片級別。
幾個問題:
你在做 IDENTIY_INSERTS 嗎?基本上指定身份值應該是什麼?或者您是否在某個時候重新設置了身份,以便插入範圍的中間?
通常,如果您正在插入,它看起來像這樣:
5 6 7 8 < Next insert goes here >
但是如果你有這樣的東西(假設你的下一個身份值為 4)
1 2 3 < Next insert goes here > 100 101
然後你可能會看到很多頁面拆分。但在正常情況下,你不應該這樣做。
你有沒有機會縮小你的數據庫?
Auto_shrink
還是會縮小的維護計劃/工作?如果是這樣,那麼導致碎片的收縮不是聚集索引。一般來說,HEAP 沒有任何問題,對於 INSERT 來說它們可以更快。我對它們最大的擔憂往往是您是否正在執行大量刪除或更新(您說您不是)。在這些情況下,您可能會出現空間洩漏並最終得到一個大小為數 GB 但有 0 行的表。
實際答案
鑑於您有一個日誌文件,並且只插入,您可以嘗試刪除 PK 並查看性能如何(當然首先在測試環境中)。一旦您使用您的工作負載執行了一些測試並了解情況如何,然後在生產中進行更改並在那裡監控一段時間。您甚至可以考慮完全刪除標識列。
不過,請檢查 SHRINK 的東西。那是一個殺手。