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

SQL Server 並行查詢優化:避免寫法導致並行被抑制的實戰案例

     編輯:關於SqlServer

並行查詢基礎

  • 針對高成本查詢,多 CPU 協同計算,最後匯總
  • 啟用閾值:Cost Threshold for Parallelism(預設 5,單位為內部成本估算值,非秒)
  • 最大平行度:Max Degree of Parallelism (MAXDOP)

問題:特定寫法抑制並行

某些 SQL 寫法會導致原本可並行的查詢退化為串行,嚴重影響效能。

案例:查詢條件使用標量函數

-- 原始查詢:並行執行,8 執行緒,130ms
SELECT * FROM LargeTable WHERE CreateDate > '2015-01-01';

-- 建立無實質邏輯的函數
CREATE FUNCTION Fn_JustFunction(@D DATE) RETURNS DATE AS BEGIN RETURN @D END;

-- 修改條件:CreateDate > dbo.Fn_JustFunction('2015-01-01')
-- 結果:串行執行,單 CPU 80%,4000ms(慢 30 倍)

案例:連接條件使用函數

SELECT * FROM TableA A
INNER JOIN TableB B ON A.Id = B.Id AND A.Col = dbo.Func(@Var)
WHERE ...;

同樣導致並行抑制。

解決方案:預先計算至變數

-- 查詢條件
DECLARE @Dt DATE = dbo.Fn_JustFunction('2015-01-01');
SELECT * FROM LargeTable WHERE CreateDate > @Dt;  -- 恢復並行

-- 連接條件
DECLARE @Val INT = dbo.Func(@Var);
SELECT * FROM TableA A
INNER JOIN TableB B ON A.Id = B.Id AND A.Col = @Val
WHERE ...;

根因分析

  • 查詢優化器在編譯階段無法內嵌/評估標量函數
  • 為保守起見,選擇串行計劃避免並行協調開銷
  • 此現象與「欄位上使用函數導致索引失效」完全不同,純粹影響並行決策

其他可能抑制並行的模式

  • 資料表變數(無統計資訊)
  • 某些 CLR 函數
  • 游標操作
  • 動態 SQL 特定模式

實務檢查清單

  • ❌ WHERE 子句直接呼叫函數
  • ❌ JOIN ON 條件直接呼叫函數
  • ✅ 先計算結果存入變數/參數,再用於查詢
  • ✅ 使用 OPTION (RECOMPILE) 獲取參數值後的最佳計劃(參數嗅探場景)

總結

並行查詢能充分利用多核 CPU,但查詢條件/連接條件直接使用函數會導致優化器退守串行。解決核心:**預先計算 → 變數/參數傳入**。SQL 優化需兼顧索引使用與並行決策,細節決定成敗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved