生產環境中,SQL 陳述式若硬編碼索引提示 (WITH (INDEX(...))),可能導致優化器無法選擇更優計畫。修改程式碼需部署流程,耗時較長。本文介紹追蹤旗標 8602,可在不修改 SQL 的情況下忽略索引提示,快速驗證效能問題。
WITH (INDEX(IX_xttrace_bal)) 強制使用特定索引。DBCC TRACEON(8602, -1) 啟用後,SQL Server 會忽略所有查詢與預存程序中的索引提示。
USE master;
GO
IF DB_ID('Trace8602') IS NOT NULL DROP DATABASE Trace8602;
GO
CREATE DATABASE Trace8602;
GO
USE Trace8602;
GO
CREATE TABLE xttrace8602
(
id INT IDENTITY(1,1) PRIMARY KEY,
bal INT,
name VARCHAR(100)
);
GO
CREATE NONCLUSTERED INDEX IX_xttrace8602_bal_name ON xttrace8602(bal, name);
GO
CREATE NONCLUSTERED INDEX IX_xttrace8602_bal ON xttrace8602(bal);
GO
INSERT INTO xttrace8602 VALUES (RAND() * 786, 'cnblogs.com/lyhabc');
GO 10000
CREATE PROC uspFirst
AS
SELECT id, name
FROM xttrace8602 TF WITH (INDEX (IX_xttrace8602_bal))
WHERE bal < 100;
GO
EXEC uspFirst;
-- 執行計畫顯示:Index Seek (IX_xttrace8602_bal) + Key Lookup
DBCC TRACEON(8602, -1);
GO
DBCC FREEPROCCACHE; -- 清除計畫快取確保重新編譯
GO
EXEC uspFirst;
-- 執行計畫顯示:Index Seek (IX_xttrace8602_bal_name) 無 Key Lookup,效能更優
-1 參數表示全域啟用 (Session 級別用 -1 以外的值或無參數)。DBCC FREEPROCCACHE 或 sp_recompile 使現有計畫失效重新編譯。INDEX, FORCESEEK 等),不影響其他提示 (如 FORCE ORDER)。| 適用場景 | 風險與注意 |
|---|---|
| 生產環境緊急效能排查,驗證索引提示是否為瓶頸 | 全域啟用影響所有查詢,可能導致原本受益於提示的查詢效能下降 |
| 開發/測試環境批次驗證舊程式碼的索引提示合理性 | 旗標重啟後失效,非永久方案 |
| 無法立即修改應用程式 SQL 時的臨時繞過方案 | 根本解決仍需移除硬編碼提示,交由優化器動態選擇 |
DBCC TRACEOFF(8602, -1))。追蹤旗標 8602 是 DBA 緊急效能排查的利器,但切記:它是診斷工具,非長期解方。