首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 查詢效能優化實戰:從子查詢到聯結、索引覆蓋與統計維護

     編輯:關於SqlServer

查詢效能優化核心三板斧:改寫邏輯、建立覆蓋索引、維護統計資料。本文以實測數據示範逐步優化過程。

優化原則速查

  • EXISTS 替代 IN:EXISTS 只需判斷是否存在,遇真即停;IN 需掃描完整子查詢結果集。
  • NOT EXISTS 替代 NOT IN:NOT IN 含 NULL 時語意陷阱且全表掃描;NOT EXISTS 安全高效。
  • 避免 SELECT *:只取需要欄位,利用覆蓋索引消除鍵查閱。
  • 參數化查詢:重用執行計畫,防注入。

實測環境與基準

  • 硬體:P4 2.4GHz、1GB RAM、Windows 2003、SQL Server 2000。
  • 測試表 t_userinfo:userid (PK), nick, classid, writetime。
  • 資料量:百萬級。

Step-by-Step 優化示範

Step 1:建表與基準測試

CREATE TABLE t_userinfo (
    userid INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
    nick VARCHAR(50) NOT NULL DEFAULT '',
    classid INT NOT NULL DEFAULT 0,
    writetime DATETIME NOT NULL DEFAULT GETDATE()
);

Step 2:建立覆蓋索引

CREATE INDEX IX_t_userinfo_classid_writetime
ON t_userinfo (classid, writetime) INCLUDE (nick);
-- 查詢:SELECT nick FROM t_userinfo WHERE classid = 5 ORDER BY writetime DESC
-- 可直接由索引滿足,無需鍵查閱

Step 3:子查詢改寫為聯結

-- 原始:相關子查詢逐列執行
SELECT u.nick, (SELECT COUNT(*) FROM t_userinfo v WHERE v.classid = u.classid) AS Cnt
FROM t_userinfo u WHERE u.userid = 100;

-- 優化:衍生表聯結
SELECT u.nick, agg.Cnt
FROM t_userinfo u
JOIN (SELECT classid, COUNT(*) AS Cnt FROM t_userinfo GROUP BY classid) agg
  ON u.classid = agg.classid
WHERE u.userid = 100;

Step 4:統計資料維護排程

-- 每日低峰期執行
UPDATE STATISTICS t_userinfo WITH FULLSCAN;
-- 或啟用資料庫層級
ALTER DATABASE TestDB SET AUTO_UPDATE_STATISTICS ON;
ALTER DATABASE TestDB SET AUTO_UPDATE_STATISTICS_ASYNC ON;  -- 非同步更新,避免查詢等待

實測結果對比

結語

百萬級資料若配合覆蓋索引、聯結改寫、統計資料維護,查詢穩定在十幾毫秒內完成。優化非黑魔法,而是系統性應用「改寫、索引、統計」三大工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
查詢模式耗時 (ms)IO (邏輯讀取)
子查詢 + 無索引12,4501,240,000
聯結 + 覆蓋索引1812