Literal, Variable與Parameter
繼續研究不同SQL寫法對執行計劃的影響。 如果大家讀過 上一篇筆記 ,就會知道以下兩則查詢將使用不同的執行計劃,前者走Clustered Index Scan,後者則是Index Seek + Key Lookup。 排版顯示 純文字 SELECT ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE ProductID = 870 --4688筆 SELECT ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE ProductID = 897 --2筆 經實測,執行計劃正如預期: 那,如果我將SQL改成這樣呢?將原本寫死的WHERE條件,改用變數(Variable)傳入,仍然查詢870跟897: 排版顯示 純文字 DECLARE @p INT SET @p = 870 SELECT ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE ProductID = @p --4688筆 SET @p = 897 SELECT ProductID, OrderQty FROM Sales.SalesOrderDetail WHERE ProductID = @p --2筆 查詢結果筆相同,但執行計劃變了,二者都走Index Scan: 呃,為什麼?上回不是說資料筆數少用Index Seek,筆數多用Index Scan,這回又不照規矩來,SQL Server你搞得我好亂吶~ 莫驚慌,SQL這麼做有它的理由,不是故意要把大家搞瘋。要找出最適合的執行計劃,全靠執行前對SQL指令進行分析。當我們使用WHERE ProductID = 897(把比對值直接寫在指令裡,術語稱為Literal),SQL分析時已知搜尋對象為ProductID 897,由統計資料預測結果筆數不多,使用Index Seek效率較佳;而宣告變數(Variable),指定變數值再WHERE ProductID = @p的做法,SQL於執行前無從得知@p的內容(雖然指令中有SET ...