1. 程式人生 > >執行計劃的生成

執行計劃的生成

根據 階段 應用 roc 詳細 控制 完成 應用程序 比較

SQL Server使用許多技術來優化資源消耗:

  • 基於語法的查詢優化;
  • 無用計劃匹配以避免對簡單查詢的深度優化;
  • 根據當前分布統計的索引和連接策略;
  • 多階段的查詢優化以控制優化開銷;
  • 執行計劃緩沖以避免重新生成執行計劃;

  以上技術按以下順序執行:

  • 解析器;
  • 代數化器;
  • 查詢優化器;
  • 執行計劃生成,緩沖和hash計劃生成;
  • 查詢執行;

  其執行順序如下:

  技術分享圖片

一、解析器(parser)

  當查詢被提交時,SQL Server將它傳遞給關系引擎中的解析器。

  •   關系引擎-負責解析、名稱和類型解析、優化和按照查詢執行計劃執行查詢並從存儲引擎請求數據;
  •   存儲引擎-負責數據訪問、修改、緩沖;

  解析器檢查進入的查詢,驗證其語法是否正確。如果發現一個語法錯誤則查詢被終止。如果多個查詢作為一個批被一起提交,如下:

CREATE TABLE t1(c1 INT)
INSERT INTO t1 VALUES(1)
AELECE * FROM t1    --註意,SELECT拼寫錯誤
GO

  解析器檢查整個批的語法並在發現語法錯誤時撤銷整個批(批中可能出現多個語法錯誤,但是解析器發現第一個錯誤後就不再繼續,所以批中有語法錯誤時代碼是一行都不會執行的。)在驗證查詢的語法時,解析器為代數化器生成一個稱為解析樹的內部數據結構。解析器和代數化器被統稱為查詢編譯。

二、代數化器(Algebrizer)

  解析器生成的解析樹被傳遞到代數化器處理。代數化器解析不同對象的所有名稱,也就是T-SQL引用的表、列等。它還確認所有被處理的不同數據類型,甚至還檢查聚合(GROUP BY、MAX)的位置。所有這些驗證和解析的輸出是被稱為查詢處理器樹的二進制數據集。

  為了了解代數化器的運行,提交以下批查詢:

CREATE TABLE t1(c1 INT);
INSERT INTO t1 VALUES(1);
SELECT ‘Before Error‘,c1 FROM t1 AS t;
--下面的沒執行 SELECT ‘error‘,c1 FROM no_t1; --no_t1表不存在 SELECT ‘after error‘ c1 FROM t1 AS t;

  對於以上語句,頭3條被執行了。錯誤及之後的語句被撤銷了。

  如果查詢包含一個隱含的數據轉換,規範化進程在查詢樹中添加一個正確的步驟。該進程還執行一些基於語法的優化。如:

SELECT * FROM Person WHERE Id BETWEEN 100 and 150

  則基於語法的優化將轉換該查詢的語法。

  對於大部分數據定義語言(DDL)語句(如CREATE TABLE、CREATE PROC等)來說,在通過代數化器之後,該查詢直接被編譯以執行,因為優化器不需要在多種處理策略中選擇。對於特別的DDL語句CREATE INDEX,優化器可以根據其他表上現有的索引來決定一個有效的處理策略。

  因此,執行計劃中不會看到對CREATE TABLE的引用,但是會看到CREATE INDEX的引用。如果規範化的查詢時一條數據操縱語言(DML)語句,則查詢處理器樹被傳遞給優化器以決定該查詢的處理策略。

  技術分享圖片

三、優化

  根據查詢的復雜度,包括引用的表和可用的索引數量,查詢處理器樹中包含的查詢可能由多種知心方式。完全比較所有執行查詢方式的開銷可能要花費較多的時間,有時即使找到最優化查詢也是得不償失。為了避免過多的優化開銷,優化器采用不同的技術,包括:

  • 無用計劃匹配;
  • 多階段優化;
  • 並行計劃優化;

  1、無用計劃匹配

  有時候可能只有一種執行查詢的方式。例如,堆表只能通過表掃描來獲取數據,為了避免浪費時間來優化這種查詢,SQL Server維護了一個無用計劃列表供選擇,如果優化器在無用列表中發現與查詢有匹配的計劃,則生成相似的計劃而不再做任何優化。

  2、多階段優化

  對於復雜的查詢,需要分析的替代處理策略數量可能很大,評估每個選擇可能花費很長的時間。因此,優化器不分析所有可能的處理策略,而是將他們分為幾種配置,每個配置含不同的索引和連接技術。

  索引變種考慮不同的索引特性,單列索引、復合索引、索引列順序、索引密度等。相似地,連接變種考慮SQL Server中可用的不同連接技術:嵌套循環連接、合並連接和哈希匹配。

  技術分享圖片

  優化器考慮WHERE子句中引起的列的統計以評估索引和連接策略的有效性。根據當前的統計,它在多個優化階段中評估配置的開銷。開銷包括許多因素,包含執行查詢所需要的CPU、內存的使用和磁盤I/O。每個優化階段之後,優化器評估處理策略的開銷。如果開銷足夠經濟,優化器停止在優化階段進一步循環並退出優化過程。否則繼續在優化階段中循環以確定一個高成本效益的處理策略。

  有時候查詢可能太復雜,以至優化器必須廣泛地在優化階段中循環。在優化查詢時,如果發現處理策略的開銷高於並行開下閾值,則使用多個CPU評估處理該查詢的開銷。否則,優化器使用串行計劃。

  • 緩沖計劃的大小;
  • 用於編譯該計劃的CPU周期;
  • 使用的內存量;
  • 編譯時間;

  優化水平屬性說明優化器中出現的處理類型。在這個例子中,FULL表示優化器進行了完全優化。這在屬性“語句終端原因”中進一步提示,原因是“找到足夠好的計劃”。所以,優化器花費21ms來捕捉到這種情形下被認為足夠好的計劃。還可以查看執行計劃的查詢計劃hash值。

  第二個優化器信息原來是動態管理視圖sys.dm_exec_query_optimizer_info。這個DMV是優化事件的集合體,它不會顯示給定查詢的單獨優化,但是可以跟蹤行的優化。這不能直接用於調整單個查詢,但是如果打算隨時減少工作負載的開銷,跟蹤這些信息能夠能幫助確定查詢調整是否產生正面的影響,至少在優化時間方面,一些返回的數據只用於SQL Server內部。.

  執行如下查詢:

SELECT Counter,Occurrence,Value FROM sys.dm_exec_query_optimizer_info

  在一組優化之前和之後運行這個查詢,可以看到完成的優化數量和類型的變化。

  3、並行計劃優化

  優化器在評估處理查詢的開銷時使用並行計劃考慮各種因素。

  • 可用於SQL Server的CPU數量;
  • SQL Server版本;
  • 可用內存;
  • 執行的查詢類型;
  • 給定流中處理的行數;
  • 活動的冰法連接數量;

  如果只有一個CPU可用於SQL Server,優化器不會考慮並行計劃。可用於SQL Server的CPU數量可以使用SQL Server配置的affinity mask設置來顯示。affinity mask值是一個位圖,一位代表一個CPU,最右邊的位置代表CPU0。例如,在8路的計算機只允許SQL Server使用CPU0-CPU3,執行如下語句:

USE master
EXEC sp_configure ‘show advanced option‘, ‘1‘
RECONFIGURE
EXEC sp_configure ‘affinity mask‘, 15 --位圖:00001111
RECONFIGURE

  這個配置立即生效。affinity mask是一個特殊的設置,建議只在剝奪SQL Server控制權有意義的情況下使用它,例如有多個運行在相同計算機上的SQL Server實例並且希望它們互相隔離時, 要設置超過32個處理器,必須使用只在SQL Server64位版本上可用的affinity64 mask選項。還 可以使用affinity mask I/O選項來將I/O綁定到特定的處理器集。

  即使多個CPU可用於SQL Server。一個並行查詢可以使用的CPU最大數量由SQL Server配置中的max degree of parallelism設置管理。默認值為0,允許所有CPU(affinity mask設置可用的)用於並行查詢。

  如果希望運行並行查詢使用不超過CPU0-CPU3中的2個CPU,執行以下語句:

USE master
EXEC sp_configure ‘show advanced option‘,‘1‘
RECONFIGURE
EXEC sp_configure ‘max degree of parallelism‘,2    --設置查詢最高可使用2個CPU
RECONFIGURE

  這個修改立即生效,不需要重啟。max degree of parallelism設置頁可以使用MAXDOP查詢提示

  在查詢級別上控制:

SELECT * FROM Person WHERE Name=‘張三‘ OPTION(MAXDOP 2)

  修改max degree of parallelism設置最好由系統需求決定。為了限制與操作系統爭用,通常將   max degree of parallelism設置為比服務器CPU數量少1,並將affinity mask也設置為這些CPU。

  因為並行查詢需要更多內存,所以優化器在選擇並行計劃之前需確定可用內存的數量。所需內存的數量隨著並行程序而增加。如果給定並行程度的並行計劃內存需求不能滿足,SQL Server將自動降低並行程度或者在給定的工作負載上下文中完全放棄並行計劃。

  具有非常高的CPU開銷的查詢時並發計劃的最佳候選。如包含連接大的表,執行大量的聚合運算,以及排序大的結果集。對於通常在事務處理應用程序中找到的簡單查詢來說,初始化、同步和停止並行計劃所需的額外調整超過了潛在的性能優勢。

  查詢是否簡單通過比較估算的執行時間和開銷閾值來確定。這個開銷閾值由SQL Server配置的cost threshold for parallelism設置控制。默認情況下,這個設置為5,意味著如果串行計劃估算的執行時間超過5秒,則優化器考慮使用並行計劃。例如,要將開銷閾值修改為6秒,執行以下語句:

USE master
EXEC sp_configure ‘show advances option‘,‘1‘
RECONFIGURE
EXEC sp_configure ‘cost threshold for parallelism‘,6
RECONFIGURE

  這個修改不需要重啟立即生效。如果只有一個CPU可用於SQL Server,這個設置將被忽略。OLTP系統會因為並行性閾值設置太低而受到損害。通常將這些值增加到15-25秒之間比較有利。

  DML操作查詢(INSERT、UPDATE和DELETE)串行查詢。但是,INSERT語句的SELECT部分和UPDATE或DELETE語句的WHERE語句可以並行執行。實際的數據修改被嚴格地應用到數據庫。而且,如果優化器確定所影響的行太少,它不會引入並行操作符。

  註意,即使在執行時,SQL Server確定當前系統工作負載和配置信息是否允許並行查詢計劃。如果允許並行查詢計劃,SQL Server確定現成的最有數量並將查詢的執行分布到這些線程。當查詢開始並行執行,它使用相同的線程數量直到完成。SQL Server在下次執行並行查詢時重新檢查最優線程數量。

  處理策略被使用串行或並行計劃定稿之後,優化器為查詢生成後執行計劃。該執行計劃包括優化器確定的執行該查詢的詳細處理策略。這包括諸如數據檢索、結果集連接、結果集排序等步驟。

  生成的查詢計劃被保存在計劃緩沖中供未來使用。

執行計劃的生成