Sql-Server

如何確定創建索引的成本?

  • March 14, 2019

我有一個表,我想在其上創建索引以提高SELECT使用該表的幾個查詢的性能。

如何測試索引是否對錶上的 DUI 操作有任何重大不利影響?

該表是一個日誌表,因此經常被寫入。是否在創建所需索引之前和之後對該表執行特定INSERT或查詢?UPDATE

如果您有一個非生產環境,您可以通過執行SQL Query Stress來模擬您的插入/更新工作負載。在添加索引以獲得基線之前執行此操作,然後查看它有多慢,以及該更改是否可以接受。

除了 DUI 操作的額外成本之外,另一個考慮因素是阻塞。您可能有與以往不同的阻塞模式,因為某些SELECT查詢將使用新索引,並且插入/更新必須對該索引聚集索引進行鎖定。

我只是指出這一點是為了表明 DUI“成本”不是唯一的考慮因素。添加索引通常可以幫助阻止,因為在更窄的 NC 索引上的 SELECT 查詢不會被聚集索引中其他列的更新阻塞。


在對您的表一無所知的情況下,這裡是 SQL 查詢壓力方法可能是什麼樣子的快速演練。我將在一個新數據庫中設置一個“LogTable”:

USE [master];
GO

CREATE DATABASE [232113];
GO

ALTER DATABASE [232113] SET RECOVERY SIMPLE WITH NO_WAIT;
GO

USE [232113];
GO

CREATE TABLE dbo.LogTable
(
   Id INT PRIMARY KEY IDENTITY(1,1),
   Col1 DATETIME NOT NULL,
   Col2 CHAR(4) NOT NULL
);

然後我使用這兩個查詢來模擬 INSERT / UPDATE 工作負載:

-- insert a row
INSERT INTO dbo.LogTable
   (Col1, Col2)
VALUES
   (GETDATE(), 'val2');

-- update a random row
UPDATE dbo.LogTable
SET Col2 = 'val3'
WHERE Id = (SELECT TOP (1) Id 
           FROM dbo.LogTable 
           ORDER BY NEWID());

然後我在 6 個執行緒上執行 SQL Query Stress,每個執行緒 250 次迭代,每次執行之間有 100 毫秒的延遲。這在大約 25 秒內完成,僅使用了聚集索引。

SQL 查詢壓力結果的螢幕截圖

現在我將在 Col2 上創建一個非聚集索引,它受插入和更新的影響:

CREATE NONCLUSTERED INDEX IX_Col2 ON dbo.LogTable (Col2);

再次執行測試,花費的時間基本相同(25 秒)。請注意,邏輯讀取增加了,所以這裡有一些成本(它只是不影響整體持續時間)。

SQL 查詢壓力結果的螢幕截圖

當然,這是一個非常簡單的案例,“伺服器”(我的筆記型電腦)上沒有其他活動,因此差異很小。但希望它展示了這個概念。

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