SQL 陳述式處理

處理單一 SQL 陳述式是 SQL Server 執行 SQL 陳述式最基本的方法。用於處理僅參考本機基底資料表 (非檢視或遠端資料表) 之單一 SELECT 陳述式的步驟可以說明這種基本的處理情況。

最佳化 SELECT 陳述式

SELECT 陳述式是非程序性的,它無法陳述資料庫伺服器應用以擷取所需資料的正確步驟。這是表示資料庫伺服器應該先分析陳述式,才能判斷出取得所需資料的最有效方式。這便稱為最佳化 SELECT 陳述式。執行此動作的元件稱為查詢最佳化工具。最佳化工具的輸入是由查詢、資料庫結構描述 (資料表和索引定義) 以及資料庫統計資料所組成。最佳化工具的輸入是查詢執行計畫,有時又稱為查詢計畫或只是計畫。在本主題稍後將更詳盡地描述查詢計畫的內容。

下圖說明在單一 SELECT 陳述式最佳化期間,查詢最佳化工具的輸入與輸出。

SELECT 陳述式的查詢最佳化

SELECT 陳述式僅定義下列項目:

  • 結果集的格式。這大部份是在選取清單中指定。然而,其他如 ORDER BY 和 GROUP BY 等子句也會影響結果集的最後格式。

  • 包含來源資料的資料表。這是在 FROM 子句中指定。

  • 資料表如何在邏輯上與 SELECT 陳述式的目的產生關聯。這是定義在聯結規格中,這些規格有可能出現在後面接著 FROM 的 WHERE 子句或是 ON 子句中。

  • 來源資料表中的資料列條件必須符合 SELECT 陳述式中所限定的條件。這些是在 WHERE 和 HAVING 子句中指定。

查詢執行計畫是用以定義下列項目:

  • 存取來源資料表的順序。

    一般而言,資料庫伺服器存取基底資料表以建立結果集的順序有很多種。例如,如果 SELECT 陳述式參考三種資料表,則資料庫伺服器可能會先存取 TableA,並使用 TableA 中的資料來取得 TableB 中相符的資料列,然後再使用 TableB 中的資料來取得 TableC 中的資料。資料庫伺服器可以存取資料表的其他順序如下:

    TableCTableBTableA

    TableBTableATableC

    TableBTableCTableA

    TableCTableATableB

  • 從各資料表取得資料所用的方法。

    一般而言,有各種不同的方式可存取每個資料表中的資料。如果僅需要特定索引鍵值的一些資料列,則資料庫伺服器可以使用索引。如果需要資料表中的所有資料列,則資料庫伺服器可以忽略索引,並執行資料表掃描。如果需要資料表中的所有資料列,但其中有一個索引的關鍵資料行是在 ORDER BY 中,那麼執行索引掃描來替代資料表掃描,將可儲存不同排序的結果集。如果資料表非常小,則資料表掃描可能是所有資料表存取中最有效率的方式。

從許多可能的計畫中選擇其中一個執行計畫的程序,便稱為最佳化。查詢最佳化工具是 SQL 資料庫系統中最重要的元件之一。因為查詢最佳化工具使用部份負擔來分析查詢並選取計畫,所以當查詢最佳化工具挑出最有效率的執行計畫時,這個負擔通常已經儲存了好幾層。例如,兩家營造公司可能對同一間房屋有相同的藍圖。如果有一家公司在剛開始時,願意花幾天的時間計畫將如何建造房屋,而另一家公司則不計畫就開始建造,那麼有花時間規劃其專案的公司,最有可能在第一時間完成。

SQL Server 查詢最佳化工具是以成本為基礎的最佳化工具。每個可能的執行計畫都有計算所使用資源量的相關成本。查詢最佳化工具必須分析可能的計畫並選擇最低估計成本的計畫。有一些複雜的 SELECT 陳述式有數以千計可能的執行計畫。在這樣的情況下,查詢最佳化工具不會分析所有可能的組合。相反的,它會使用複雜的演算法來尋找最接近最小可能成本的執行計畫。

SQL Server 查詢最佳化工具並不僅是選擇最低資源成本的執行計畫,也選擇傳回給使用者的結果中,具合理的資源成本,以及傳回結果速度最快的計畫。例如,一般平行處理查詢時,需使用比循序處理時使用更多的資源,但完成的速度較快。如果伺服器的負載不會受到負面的影響,則 SQL Server 最佳化工具將使會使用平行執行計畫來傳回結果。

查詢最佳化工具在估計以不同方法擷取資料表或索引中資訊的資源成本時,是根據散發統計資料。散發統計資料適用於資料行和索引。他們可指出特殊索引或資料行中值的選擇性。例如,在表示車種的資料表中,許多車種的製造商都是相同的,但每輛車都有一個唯一的汽車識別號碼。因此索引 VIN 比索引製造商更具選擇性。如果目前沒有索引統計資料,則最佳化工具可能無法針對目前的資料表狀態做出最佳選擇。如需保持目前索引統計資料的詳細資訊,請參閱<使用統計資料來改善查詢效能>。

查詢最佳化工具非常重要,因為它可以讓資料庫伺服器進行動態調整,以變更資料庫中的情況,而不需要由程式設計人員或資料庫管理員來輸入。這樣程式設計師便不用將焦點集中在描述查詢的最後結果。他們可以相信每次執行陳述式時,查詢最佳化工具將依資料庫的狀態建立最有效率的執行計畫。

處理 SELECT 陳述式

SQL Server 處理單一 SELECT 陳述式所使用的基本步驟如下:

  1. 剖析器會先掃描 SELECT 陳述式,並將其分成數個邏輯單位,如關鍵字、運算式、運算子和識別碼。

  2. 然後系統會建立查詢樹 (有時也稱為序列樹),描述將來源資料轉換成結果集所需格式的邏輯步驟。

  3. 查詢最佳化工具會分析可存取來源資料表的數種方式。接著它會選取一系列的步驟,以利使用更少的資源以最快的速度傳回結果。將會更新查詢以記錄所有的系列步驟。查詢樹的最後最佳版本就稱為執行計畫。

  4. 關聯式引擎開始執行執行計畫。當在處理需要基底資料表中資料的步驟時,關聯式引擎會要求儲存引擎,從取自關聯式引擎的資料列集中傳回資料。

  5. 關聯式引擎處理從儲存引擎傳回的資料,並將其設定成結果集所定義的格式,然後將結果集傳回給用戶端。

處理其他的陳述式

這裡所描述用以處理 SELECT 陳述式的基本步驟,僅適用於其他 SQL 陳述式,例如 INSERT、UPDATE、及 DELETE。UPDATE 與 DELETE 陳述式兩者都必須有要修改或要前除的目標資料列集。識別這些資料列的處理序與用以識別 SELECT 陳述式產生結果集之來源資料列的處理序相同。UPDATE 和 INSERT 陳述式兩者可能都含有內嵌的 SELECT 陳述式,此陳述式可提供要更新或插入的資料值。

即使是資料定義語言 (DDL) 陳述式 (如 CREATE PROCEDURE 或 ALTER TABLE) 最後都會解析成系統目錄資料表上一連串的關聯式作業,而有時則成為資料表上的關聯式作業 (如 ALTER TABLE ADD COLUMN)。