SQL Server 利用Profiler觀察執行計劃是否重用時SP:Cachemiss,SP:CacheInsert以及SP:CacheHit的含義

来源:http://www.cnblogs.com/wy123/archive/2017/05/27/6913055.html
-Advertisement-
Play Games

本文出處:http://www.cnblogs.com/wy123/p/6913055.html 執行計劃的緩存與重用 在通過SQL Profile觀察一個SQL語句或者存儲過程是否有可用的緩存執行計劃的時候,通過SP:CacheMiss和SP:CacheHit事件可以說明是否發生了編譯/重編譯和是 ...


 

本文出處:http://www.cnblogs.com/wy123/p/6913055.html 

 

 

執行計劃的緩存與重用

在通過SQL Profile觀察一個SQL語句或者存儲過程是否有可用的緩存執行計劃的時候,
通過SP:CacheMiss和SP:CacheHit事件可以說明是否發生了編譯/重編譯和是否重用了緩存的執行計劃,
但是對於SP:CacheMiss這一細節,還是存在不少理解錯誤的情況的,本文通過一個簡單的例子來解釋說明SP:CacheMiss所表達的真實含義。

簡單建個測試表,來測試使用

CREATE TABLE Test
(
    Id INT,
    NAME VARCHAR(100)
)
GO

DECLARE @i INT = 0
WHILE @i<100000
BEGIN
    INSERT INTO Test VALUES(@i,NEWID())
    SET @i = @i+1
END
GO

CREATE INDEX IX_Id ON Test(Id)
GO

 

如何利用Profile觀察SQL語句的執行計劃的編譯/重編譯和重用?

  眾所周知的,參數化SQL的執行計劃可以緩存並重用,那麼就以如下一個簡單的參數化SQL為例,觀察在傳入不同參數時的執行計劃重用現象
  下麵是兩個參數化的SQL語句,語句的主體都是一樣的,只是帶入的參數不同,正常情況下,第二句代碼是可以重用第一句代碼執行之後緩存的執行計劃的。

  至於怎麼開Profile就不說了,基礎問題。

 

SP:CacheInsert和SP:CacheHit

  執行上述代碼,如下

DBCC FREEPROCCACHE
GO

EXEC SP_EXECUTESQL N'SELECT * FROM [dbo].[Test] WHERE Id = @id', N'@id INT',@id =9999
GO

EXEC SP_EXECUTESQL N'SELECT * FROM [dbo].[Test] WHERE Id = @id', N'@id BIGINT',@id =201
GO

  得到的Profile中跟蹤的信息如下

  簡單說明一下,執行第一句代碼之前,是清空了執行計劃緩存的,所以第一次執行的sql語句是沒有執行計劃緩存可用的。

  參考截圖。

  首先看第一次執行的情況:
    上面說了,執行第一句代碼之前,是清空了執行計劃緩存的,所以第一次執行的sql語句是沒有執行計劃緩存可用的。
    因此第一句SQL代碼是需要編譯的(不是重編譯),
    參數化SQL編譯之後要緩存起來(不同參數可以重用執行計劃),表現就是有一個SP:CacheInsert。
    SP:CacheInsert的意思是當前SQL編譯,生成了一個執行計劃,並且向緩存中插入一個執行計劃緩存。
  然後看第二次執行的情況:
    在第二句SQL執行的時候,因為第一句SQL已經編譯並且緩存了一個執行計劃,
    因此當前SQL是不需要編譯,並且可以重用已有的執行計劃的。
    這個就表現在有一個SP:CacheHit,
    SP:CacheHit的意思就是,當前SQL的執行計劃在緩存的執行計劃中命中。

 

為什麼第一次和第二次都會出現一個“SP:CacheMiss”事件

  為什麼第一次和第二次都會出現一個“SP:CacheMiss”事件?
  上面不是說第二個SQL的執行已經重用了第一次的執行計划了嗎,為什麼還會出現“SP:CacheMiss”事件?
  “SP:CacheMiss”事件到底代表什麼含義?
  原因就是:
  SQL Server在緩存執行計劃的時候,只緩存SQL語句本身,而不緩存執行的語句。
  聽起來這麼彆扭,還是以實例來說明吧,參考下圖,緩存就是換成的語句本身,而不是整個執行的字元串信息
  因此“SP:CacheMiss”代表的是:“EXEC SP_EXECUTESQL N'SELECT * FROM [dbo].[Test] WHERE Id = @id', N'@id INT',@id =8888”這個字元串。

  

   關於上述結論再舉一例:

   如果上述實例不足以說明問題的話,再舉一個例子,這裡創建一個沒有任何參數和動態SQL的存儲過程(不會導致每次執行都重新編譯,執行計劃會重用),
   正常情況下,該存儲過程第一次執行之後,執行計劃會被緩存起來,第二次執行的時候就可以重用第一次的執行計劃。

  

   這裡情況緩存的執行計劃,連續執行兩次EXEC TestPlanCache,觀察Profile中的現象,是不是還是每次執行仍有有一個SP:CacheMiss事件?
   為什麼,難道說還是因為沒有緩存可用嗎?
   肯定不是,第一次執行仍舊是有一個SP:CacheInsert,第二次仍舊是SP:CacheHit,跟上述發生執行計劃重用的現象一致。
   結論仍舊一樣,與上面所述類似,SQL Server不會緩存EXEC TestPlanCache這個文本本身,緩存的執行計劃是內部的SQL語句的執行計劃,
   SP:CacheMiss是針對EXEC TestPlanCache這個命令來說的,SQL Server是不緩存調用存儲過程或者參數化SQL的命令本身的。

   

總結:

有人在觀察執行計劃緩存與重用的時候,尤其是存儲過程或者sp_executesql執行的參數化SQL語句,
會發現不停地出現SP:CacheMiss事件,就武斷地斷定為發生了編譯/重編譯,
編譯與重編譯是針對SQL語句或者存儲過程中的SQL來說的,而不是針對調用存儲過程或者參數化SQL的命令本身來說的。
SQL Server自身不會緩存調用存儲過程或者參數化SQL的命令本身,因此會經常發現SP:CacheMiss事件。
對於SQL語句的計劃緩存,如果是第一次編譯,會緩存起來,緩存的時候就會出現SP:CacheInsert,第二次或者以後重用這個計劃,就是出現SP:CacheHit事件。

 


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

-Advertisement-
Play Games
更多相關文章
  • 今天將項目從ionic2 升級為ionic3 ,ionic serve 運行在網頁上無任何錯誤。 但是將項目打包成為android apk 卻一直卡在啟動頁面 白屏,進不去的情況。後來在android studio 控制台看到這個錯誤提示:Uncaught SyntaxError Use of co ...
  • 一,效果圖。 二,工程圖。 三,代碼。 RootViewController.h RootViewController.m ...
  • 《NoSQL精粹》為考慮是否可以使用和如何使用NoSQL資料庫的企業提供了可靠的決策依據。它由世界軟體開發大師和軟體開發“教父”Martin Fowler與Jolt生產效率大獎圖書作者Pramod J. Sadalage共同撰寫。書中全方位比較了關係型資料庫與NoSQL資料庫的異同;分別以Riak、 ...
  • 一概述 1.什麼是Mybatis? ⑴Mybatis是Apache的一個開源項目,原名為ibatis,移植到google code後改名為Mybatis,目前遷移到了Github。 ⑵Mybatis是一個支持定製化SQL、存儲過程以及高級映射的優秀持久層框架,避免了幾乎所有的JDBC代碼、手動設置參 ...
  • 5. 圖的轉換操作 圖的轉換操作主要有以下的方法: (1) Graph.mapVertices():對圖的頂點進行轉換,返回一張新圖; (2) Graph.mapEdges():對圖的邊進行轉換,返回一張新圖。 代碼: 運行結果: 6. 圖的結構操作 圖的結構操作主要有: (1) Graph.sub ...
  • Itpub上遇到一個求助寫SQL的帖子,感覺很有意思,於是寫出來看看,要求如下: 於是建表插數據,表結構如下: 語句如下: 用到了nvl,case when,not in,over partition,sum,union,left join,with as等寫法,常年寫SQL的應該有更加效率的寫法, ...
  • 首先請確認正確安裝好MySQL. 1- 先配置環境變數path 1.1 打開終端,輸入: cd ~ 會進入~文件夾, 1.2 然後輸入:touch .bash_profile 回車執行後, 1.3 再輸入:open -e .bash_profile 會在TextEdit中打開這個文件(如果以前沒有配 ...
  • 《大數據時代》是國外大數據系統研究的先河之作,本書作者維克托.邁爾.舍恩伯格被譽為“大數據商業應用一人”,擁有在哈佛大學、牛津大學、耶魯大學和新加坡國立大學等多個互聯網研究重鎮任教的經歷,早在2010年就在《經濟學人》上發佈了長達14頁對大數據應用的前瞻性研究。 維克托.爾耶.舍恩伯格在本書中前瞻性 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...