在SQL Server 2016里使用查詢存儲進行性能調優

来源:http://www.cnblogs.com/woodytu/archive/2016/01/21/5141092.html
-Advertisement-
Play Games

作為一個DBA,排除SQL Server問題是我們的職責之一,每個月都有很多人給我們帶來各種不能解釋卻要解決的性能問題。我就多次聽到,以前的SQL Server的性能問題都還好且在正常範圍內,但現在一切已經改變,SQL Server開始糟糕, 瘋狂的事情不能解釋。在這個情況下我介入,分析下整個SQL...


作為一個DBA,排除SQL Server問題是我們的職責之一,每個月都有很多人給我們帶來各種不能解釋卻要解決的性能問題。

我就多次聽到,以前的SQL Server的性能問題都還好且在正常範圍內,但現在一切已經改變,SQL Server開始糟糕, 瘋狂的事情不能解釋。在這個情況下我介入,分析下整個SQL Server的安裝,最後用一些神奇的調查方法找出性能問題的根源。

但很多時候問題的根源是一樣的:所謂的計劃回歸(Plan Regression),即特定查詢的執行計劃已經改變。昨天SQL Server已經緩存了在計劃緩存里緩存了一個好的執行計劃,今天就生成、緩存最後重用了一個糟糕的執行計劃——不斷重覆。

進入SQL Server 2016後,我就變得有點多餘了,以為微軟引進了查詢存儲(Query Store)。這是這個版本最熱門的功能!查詢存儲幫助你很容易找出你的性能問題是不是計劃回歸造成的。如果你找到了計劃回歸,這很容易強制一個特定計劃不使用計劃嚮導。聽起來很有意思?讓我們通過一個特定的場景,向你展示下在SQL Server 2016里,如何使用查詢存儲來找出並最終修正計劃回歸。

查詢存儲(Query Store)——我的對手

在SQL Server 2016里,在你使用查詢存儲功能前,你要對這個資料庫啟用它。這是通過ALTER DATABASE語句實現,如你所見的下列代碼:

 1 CREATE DATABASE QueryStoreDemo
 2 GO
 3 
 4 USE QueryStoreDemo
 5 GO
 6 
 7 -- Enable the Query Store for our database
 8 ALTER DATABASE QueryStoreDemo
 9 SET QUERY_STORE = ON
10 GO
11 
12 -- Configure the Query Store
13 ALTER DATABASE QueryStoreDemo SET QUERY_STORE
14 (
15     OPERATION_MODE = READ_WRITE, 
16     CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 367), 
17     DATA_FLUSH_INTERVAL_SECONDS = 900, 
18     INTERVAL_LENGTH_MINUTES = 1, 
19     MAX_STORAGE_SIZE_MB = 100, 
20     QUERY_CAPTURE_MODE = ALL, 
21     SIZE_BASED_CLEANUP_MODE = OFF
22 )
23 GO

線上幫助為你提供了各個選項的詳細信息。接下來我創建一個簡單的表,創建一個非聚集索引,最後插入80000條記錄。

 1 -- Create a new table
 2 CREATE TABLE Customers
 3 (
 4     CustomerID INT NOT NULL PRIMARY KEY CLUSTERED,
 5     CustomerName CHAR(10) NOT NULL,
 6     CustomerAddress CHAR(10) NOT NULL,
 7     Comments CHAR(5) NOT NULL,
 8     Value INT NOT NULL
 9 )
10 GO
11 
12 -- Create a supporting new Non-Clustered Index.
13 CREATE UNIQUE NONCLUSTERED INDEX idx_Test ON Customers(Value)
14 GO
15 
16 -- Insert 80000 records
17 DECLARE @i INT = 1
18 WHILE (@i <= 80000)
19 BEGIN
20     INSERT INTO Customers VALUES
21     (
22         @i,
23         CAST(@i AS CHAR(10)),
24         CAST(@i AS CHAR(10)),
25         CAST(@i AS CHAR(5)),
26         @i
27     )
28     
29     SET @i += 1
30 END
31 GO

為了訪問我們的表,我額創建了一個簡單的存儲過程,傳入value值作為過濾謂語。

 1 -- Create a simple stored procedure to retrieve the data
 2 CREATE PROCEDURE RetrieveCustomers
 3 (
 4     @Value INT
 5 )
 6 AS
 7 BEGIN
 8     SELECT * FROM Customers
 9     WHERE Value < @Value
10 END
11 GO

現在我用80000的參數值來執行存儲過程。

1 -- Execute the stored procedure.
2 -- This generates an execution plan with a Key Lookup (Clustered).
3 EXEC RetrieveCustomers 80000
4 GO

現在當你查看實際的執行計劃時,你會看到查詢優化器已經選擇了有419個邏輯讀的聚集索引掃描運算符。SQL Server並沒有使用非聚集索引,因為這樣沒有意義,由於臨界點。這個查詢結果並沒有選擇性。

現在假設SQL Server發生了些事情(例如重啟,故障轉移),SQL Server忽略已經緩存的計劃,這裡我通過執行DBCC FREEPROCCACHE從計劃緩存里抹掉每個緩存的計劃來模擬SQL Server重啟(不要在生產環境里使用!)。

1 -- Get rid of the cached execution plan...
2 DBCC FREEPROCCACHE
3 GO

現在有人再次調用你的存儲過程,這次輸入參數值是1。這次執行計劃不一樣,因為現在在執行計劃里你會有書簽查找。SQL Server估計行數是1,在非聚集索引里沒有找到任何行。因此與非聚集索引查找結合的書簽查找才有意義,因為這個查詢是有選擇性的。

現在我再執行用80000參數值的查詢。

1 -- Execute the stored procedure
2 EXEC RetrieveCustomers 1
3 GO
4 
5 -- Execute the stored procedure again
6 -- This introduces now a plan regression, because now we get a Clustered Index Scan
7 -- instead of the Key Lookup (Clustered).
8 EXEC RetrieveCustomers 80000
9 GO

當你再次看STATISTICS IO的輸出,你會看到這個查詢現在產生了160139個邏輯讀——剛纔的查詢只有419個邏輯讀。這個時候DBA的手機就會響起,性能問題。但今天我們要不同的方式解決——使用剛纔啟用的查詢存儲。

當你再次看實際的執行計劃,在你面前你會看到有一個計劃回歸,因為SQL Server剛重用了書簽查找的的計劃緩存。剛纔你有聚集索引掃描運算符的執行計劃。這是SQL Server里參數嗅探的副作用。

讓我們通過查詢存儲來詳細瞭解這個問題。在SSMS里的對象資源管理器里,SQL Server 2016提供了一個新的結點叫查詢存儲,這裡你會看到一些報表。

【前幾個資源使用查詢】向你展示了最昂貴的查詢,基於你選擇的維度。這裡切換到【邏輯讀取次數】。

這裡在你面前有一些查詢。最昂貴的查詢生成了近500000個邏輯讀。這是我們的初始語句。這已經是第一個WOW效果的的查詢存儲:SQL Server重啟後,查詢存儲的數據還是存在的!第2個是你存儲過程里的SELECT語句。在查詢存儲里每個捕獲的查詢都有一個標示號——這裡是7。最後當你看報告的右邊,你會看這個查詢的不同執行計劃。

如你所見,查詢存儲捕獲了2個不同的執行計劃,一個ID是7,一個ID是8。當你點擊計劃ID時,SQL Server會在報表的最下麵為你顯示估計的執行計劃。

計劃8是聚集索引掃描,計劃7是書簽查找。如你所見,使用查詢存儲分析計劃回歸非常簡單。但你現在還沒結束。你現在可以對指定的查詢強制執行計劃。 現在你知道包含聚集索引掃描的執行計劃有更好的性能。因此現在你可以通過點擊【強制執行計劃】強制查詢7使用執行計劃。

搞定,我們已經解決問題了!

現在當你執行存儲過程(用80000的輸入參數值),在執行計劃里你可以看到聚集索引掃描,執行計劃只生成419個邏輯讀——很簡單,是不是?絕對不是!!!!

微軟告訴我們只給修正SQL Server性能相關的“新方式”。你只是強制了特定的計劃,一切都還好。這個方法有個大的問題,因為性能問題的根源並沒有解決!這個問題的關鍵是因為書簽查找計劃沒有穩定性。取決於首次執行計劃預設的輸入值,執行計劃因此就被不斷重用。

通常我會建議調整下你的索引設計,創建一個覆蓋索引來保證計劃的穩定性。但強制特定執行計劃只是臨時解決問題——你還是要修正你問題的根源。

小結

不要誤解我:SQL Server 2016里的查詢存儲功能很棒,可以幫你更容易理解計劃回歸。它也會幫你“臨時”強制特定的執行計劃。但性能調優的目標還是一樣:你要找到問題根源,嘗試解決問題——不要在外面晃蕩!

感謝關註!

參考文章:http://www.sqlpassion.at/archive/2016/01/18/performance-troubleshooting-with-the-query-store-in-sql-server-2016


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在ng-repeat中使用ng-model時會有許多問,有的人碰到無法獲取綁定的數據內容,有的人遇到改動綁定的數據內容時所有迴圈生成的內容一起改變。上面的問題我在開發時也遇到過,但是解決後我卻怎麼也還原不了那種情況了,只能先簡單介紹一下無法獲取的情景該如何解決。例如:html: ...
  • 前言 近來由於工作需要,需要提取某些城市的經緯度坐標,稍微搜索了一下,發現百度地圖和高德地圖都提供了相關的函數和例子.那麼剩餘的工作也就比較簡單了,保存坐標,然後轉換為WGS坐標,這樣才能和現有的GPS數據以及地圖匹配.主要問題和解決方法本地保存文件跨瀏覽器支持 由於安全的原因,JavaScript...
  • 寫網頁的時候很多情況需要對圖片進行操作,如何在不進行專業的美工裁切操作的情況下而讓自己的素材度達到最大的滿意度呢,這是一個問題,對於懶得開ps切圖的我,通常會直接在網路上download一張圖片,直接拖到html里,這就需要對圖片的css樣式進行一些調整,鑒於我總是記不住一些樣式屬性而無法讓圖片.....
  • 1 2 3 4 5 6 7 8 27 28 dian29 30 今天開始學習 dojo 目的是學習 arc gis api for jsrequire 方法:引入組件和模塊on 方法:綁定...
  • 。。。。
  • 首先說明》 FEDERATED存儲引擎訪問在遠程資料庫的表中的數據,而不是本地的表。這個特性給某些開發應用帶來了便利,你可以直接在本地構建一個federated表來連接遠程數據表,配置好了之後本地表的數據可以直接跟遠程數據表同步。實際上這個引擎裡面是不真實存放數據的,所需要的數據都是連接到其他MyS...
  • 機器學習很多場景中會用到放回采樣,比如bagging方法。
  • 上篇文章簡單討論了虛擬機的原理,這篇文章我們詳細討論下指令,具體從幾種典型的SQL語句來看看每種SQL對應的指令流,以及每個指令的含義。通過explain語句,可以看到語句對應的指令流;通過pragma vdbe_trace=on指令,我們甚至可以得到語句對應的指令執行流程,包括跳轉等。測試表結.....
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...