Sql-Server

如果桌子是堆,桌子會受益嗎

  • May 12, 2016

我有一個大約 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 的東西。那是一個殺手。

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