后面的練習中需要下載 Demo 數據庫, 有很多不同的版本, 可以根據個人需要下載. 下載地址 - http://msftdbprodsamples.codeplex.com/
1. 什么是執行計划
- 查詢優化器對輸入的 T-SQL 查詢語句通過"計算"而選擇出效率最高的一種執行方案,這個執行方案就是執行計划.
- 執行計划可以告訴你這個查詢將會被如何執行或者已經被如何執行過,可以通過執行計划看到 SQL 代碼中那些效率比較低的地方.
- 查看執行計划的方式我們可以通過圖形化的界面,或者文本,或者XML格式查看,這樣會比較方便理解執行計划要表達出來的意思.
- 系統需要更多內存的時候
- 倒數計數器減到 0 了.
- 當前的鏈接沒有引用到這個執行計划.
- Query 所引用的表或者架構等結構發生改變
- Query 所引用的索引發生改變,比如修改或者刪除了
- 調用了 sp_recompile 重新編譯的時候.
11. 查看系統中已有的執行計划
SELECT [cp].[refcounts] ,[cp].[usecounts] ,[cp].[objtype] ,[st].[dbid] ,[st].[objectid] ,[st].[text] ,[qp].[query_plan]
FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
執行結果
可以打開一個 Query Plan 來看
12. 為什么 Estimated Execution Plan 和 Actual Execution Plan 不一樣
- Estimated Execution Plan 所統計的數據和實際執行的時候數據有變化, 比如Estimated Execution Plan 創建的時候, 數據庫只有1000條數據 , 但是在實際執行的時候可能數據在這期間已經發生改變, 因此產生出來的 Actual Execution Plan 可能就不同.
- Estimated Execution Plan 實際上在關系型引擎中創建產生, 因為並不會真正執行SQL 語句. 那么類似於這樣的代碼在得到 Estimated Execution Plan 的時候會發生錯誤, 原因就是這個對象不可能在 Estimated Execution Plan 階段創建因此就會發生錯誤, 這和 Actual Execution Plan也不同.
CREATE TABLE TempTable ( Id INT IDENTITY(1, 1) ,Dsc NVARCHAR(50) ); INSERT INTO TempTable ( Dsc ) SELECT Value FROM dbo.Brand SELECT *
FROM TempTable; DROP TABLE TempTable;
如果點擊 "Display Estimated Execution Plan" 將會產生以下錯誤信息:
Msg 208, Level 16, State 1, Line 6
Invalid object name 'TempTable'.
原因就是 TempTable 是不可能在 Estimated Execution Plan 階段創建的, 因為還處於在關系引擎控制階段, 還沒有到存儲引擎.
13. Execution Plan Formats 執行計划的3種格式 (個人比較喜歡圖形執行計划, 但有時也會使用文本執行計划查看具體的數據)
- 圖形執行計划 – 非常容易查看和閱讀, 但是有一些細節數據被隱藏了
- 文本執行計划 – 讀起來有些困難, 但是很多信息可以直接查看. 文本執行計划有3種格式:
- SHOWPLAN_ALL – 顯示”估算執行計划”的所有內容
- SHOWPLAN_TEXT – 顯示一部分”估算執行計划”的內容
- STATISTICS PROFILE – 和SHOWPLAN_ALL 一樣, 不同的是它顯示的是”實際執行計划”
- XML 執行計划 - XML 執行計划能夠以XML格式反映大多數數據內容.
- SHOWPLAN_XML – 可以理解為”預估執行計划”
- STATISTICS_XML – 顯示實際執行計划
SELECT *
FROM [dbo].[DatabaseLog]
Table scan – 出現在當存儲引擎強制性的一行一行的遍歷整張表或者返回所有內容, 因為我們並沒有使用任何的 WHERE 條件並且我們也沒有使用到任何的索引(索引上應該包含它所在表上的所有列).
16.對於 Estimated Execution Plan 執行計划
查看查詢優化器給出 SELECT 操作符的執行成本情況
- Cached plan size – 在存儲過程緩存中由這個查詢語句產生的計划所占用內存的大小, 這個數字比較有用, 可以用來調查緩存的性能問題, 特別是某個計划所占的內存非常大的情況下.
- Estimated Operator Cost – 就應該是上圖中 SELECT 的耗費
- Estimated Sub tree Cost – 告訴我們這個步驟和之前所有的步驟所累加起來的一個耗費值, 但是看它之前的步驟要注意要從右往左讀, 目前 SELECT 步驟的左邊沒有其他的步驟. 這個值表示的是查詢優化器認為這個運算符可能要花費的時間.
- Estimated number of rows – 查詢優化器基於一些統計數據得到的, 這里指的是返回的行數.
查看 Table Scan
- Logical Operations – 查詢優化器認為對在 Query 語句執行時應該發生的操作 .
- Physical Operations – 實實在在發生的操作. 這兩個值大多數情況相同, 但也有不同的時候.
- Estimated number of rows – 再次看到這個值, 實際上每一個步驟的操作可能不相同, 每一個步驟要處理和傳遞的數據量大小都不一樣, 所以從每個步驟中就能看到數據量大小的變化, 有哪些增加了, 有哪些被過濾掉了, 這樣也會幫助我們理解整個流程發生了什么.
- Ordered – 告訴我們這個步驟的操作符是否對數據進行了排序操作.
17. 預估的文本執行計划 Getting the Estimated Text Plan
在啟用文本的預估執行計划時, 先要打開這個計划.
SET SHOWPLAN_ALL ON; 並且要注意在使用完了之后也一定要 SET SHOWPLAN_ALL OFF.
18. 實際文本執行計划 Getting the Actual Text Plan
SET STATISTICS PROFILE ON SET STATISTICS PROFILE OFF
19. XML 執行計划
Estimated Plan - SET SHOWPLAN_XML ON / SET SHOWPLAN_XML OFF
20. XML 實際執行計划
Actual Plan – SET STATISTICS XML ON / SET STATISTICS XML OFF
21. 如何將XML 計划保存為圖形執行計划
可以將XML 格式的執行計划保存為后綴為 “.sqlplan” 的文件, 這個文件顯示的就是圖形執行計划. 因為有的時候需要把某個執行計划的結果發給其他人來調整我們的SQL 語句.
22. 在 SQL Profiler 中自動捕獲執行計划
在實際開發過程中, 可能隨時需要查看不同SQL 語句的執行計划, 並且最好是能夠自動捕獲 SQL 的執行計划以便隨時查看有哪些查詢耗費的成本比較高, 或者像這種有 Table Scan 的情況都需要被截獲並查看他們的執行計划.
在SQL Server 2005可以通過 SQL Profiler 來幫助捕獲這些計划, 后期的版本也支持這個功能. 捕獲后的計划可以直接在SQL Profiler 中瀏覽或者保存到文件, 再或者存放到數據庫.
在 SQL Profiler 中選中以下幾種事件
-
- Showplan XML
-
- RPC:Completed
-
- SQL:BatchStarting
-
- SQL:BatchCompleted
選中 Showplan XML 事件后會出現一個新的Tab – Events Extraction Settings. 在這里可以配置 XML Execution plan 保存的地點以便以后查看, 還可以選擇將Execution Plan 保存在一個文件還是每個單獨放在一個文件里.
配置完成后點擊 ”Run”, 然后就可以在 SQL Profiler 中查看SQL 的執行計划, 並且還可以單獨保存成一個文件作為以后分析的依據.