Sql-Server
如何確定創建索引的成本?
我有一個表,我想在其上創建索引以提高
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 秒內完成,僅使用了聚集索引。
現在我將在 Col2 上創建一個非聚集索引,它受插入和更新的影響:
CREATE NONCLUSTERED INDEX IX_Col2 ON dbo.LogTable (Col2);
再次執行測試,花費的時間基本相同(25 秒)。請注意,邏輯讀取增加了,所以這裡有一些成本(它只是不影響整體持續時間)。
當然,這是一個非常簡單的案例,“伺服器”(我的筆記型電腦)上沒有其他活動,因此差異很小。但希望它展示了這個概念。