查詢效能不佳的疑難排解:基數估計

SQL Server 中的查詢最佳化工具是以成本為依據,這表示它會選取估計處理成本最低的查詢計畫來執行。查詢最佳化工具根據兩個主要因數來判斷執行查詢計畫的成本:

  • 在查詢計畫的每一個層級進行處理的資料列總數,此稱為計畫的基數。

  • 查詢中使用的運算子所指定的演算法成本模型。

第一個因數 (基數) 會作為第二個因數 (成本模型) 的輸入參數。因此,如果改善基數,便能產生更好的估計成本,進而可有更快的執行計畫。

SQL Server 主要是從建立索引或統計資料時所建立的長條圖 (透過手動或自動方式) 來估計基數。有時候,SQL Server 也會使用條件約束資訊及查詢的邏輯重寫來判斷基數。

在下列情況中,SQL Server 無法精確地計算基數。這會導致不精確的成本計算,使得產生並非最佳的查詢計畫。避免在查詢中使用這些建構可以提升查詢效能。有時也可以使用替代的查詢公式或其他方法,這些項目稍後也會提及。

  • 查詢的述詞,在相同資料表的不同資料行之間使用比較運算子。

  • 查詢的述詞使用運算子,且下列任一情況為真:

    • 運算子任一邊所關聯的資料行中,沒有任何統計資料。

    • 統計資料中的值分佈並不平均,但查詢會搜尋具有高度選擇性的值集。如果運算子不是等號 (=) 運算子,此情況會特別明顯。

    • 述詞使用不等於 (!=) 比較運算子或 NOT 邏輯運算子。

  • 使用任一個 SQL Server 內建函數或純量值之使用者自訂函數 (其引數不是常數值) 的查詢。

  • 查詢透過算術或字串串連運算子,與聯結資料行相關聯。

  • 查詢所比較的變數,在編譯及最佳化查詢時其值不明。

下列方法可用來嘗試提升這些查詢類型的效能:

  • 在查詢相關的資料行上,建立有用的索引或統計資料。如需詳細資訊,請參閱<設計索引>和<使用統計資料來改善查詢效能>。

  • 如果查詢使用比較或算術運算子來比較或結合兩個以上的資料行時,請考慮使用計算資料行並重寫查詢。例如,下列查詢會比較兩個資料行中的值:

    SELECT * FROM MyTable
    WHERE MyTable.Col1 > MyTable.Col2
    

    如果將計算資料行 Col3 加入 MyTable,用來計算 Col1Col2 的差 (Col1Col2),可以提升效能。接著,重寫查詢:

    SELECT * FROM MyTable
    WHERE Col3 > 0
    

    如果您在 MyTable.Col3 上建立索引,可能還可以更進一步提升效能。