SQLSERVER編譯與重編譯

来源:http://www.cnblogs.com/jh-1110/archive/2016/09/24/5902354.html
-Advertisement-
Play Games

SQLSERVER編譯與重編譯 編譯的含義 當SQLSERVER收到任何一個指令,包括查詢(query)、批處理(batch)、存儲過程、觸發器(trigger) 、預編譯指令(prepared statement)和動態SQL語句(dynamic SQL Statement)要完成語法解釋、語句解 ...


SQLSERVER編譯與重編譯

編譯的含義


當SQLSERVER收到任何一個指令,包括查詢(query)、批處理(batch)、存儲過程、觸發器(trigger)

、預編譯指令(prepared statement)和動態SQL語句(dynamic SQL Statement)要完成語法解釋、語句解釋,

然後再進行“編譯(compile)”,生成能夠運行的“執行計劃(execution plan)”。在編譯的過程中,

SQLSERVER會根據所涉及的對象的架構(schema)、統計信息以及指令的具體內容,估算可能的執行計劃,

以及他們的成本(cost),最後選擇一個SQLSERVER認為成本最低的執行計劃來執行。執行計劃生成之後,

SQLSERVER通常會把他們緩存在記憶體里,術語統稱他們叫“plan cache”以後同樣的語句執行,SQLSERVER就可以使用同樣的執行計劃,而無須再做一次編譯。

這種行為叫“重用(reuse)或者叫重用執行計劃”。但是有時候,哪怕是一模一樣的語句,SQL下次執行還是要再做一次編譯。

這種行為叫“重編譯(recompile)”。執行計劃的編譯和重編譯都是要消耗資源的。

如果執行計劃能夠重用,那麼SQLSERVER就不需要再執行上面的過程,加快執行指令的速度,很多語句調優的文章里提到資料庫重用執行計劃就是指這個意思

 

 

執行計劃重用的利弊


執行計劃的好壞當然決定了語句最終的執行速度。對於同樣的一條語句,使用好的執行計劃可能會比差的要快幾百倍,甚至上千倍。

所以從這一個角度來講,每運行一條語句,都把他先編譯一遍當然是最好的。他能夠保證使用的執行計劃是SQLSERVER能找到的最優的。

但是SQLSERVER每秒鐘可能會運行成百上千的指令。如果每個都編譯一遍,是資源的一種浪費。所以SQLSERVER在這裡也試圖尋找一個平衡點,

使用有限的compile/recompile,得到最好的整體性能

 

運行下麵的指令,就能夠看到SQLSERVER當前緩存的執行計劃有哪些(請別在生產伺服器上直接運行因為上面往往有龐大的緩存)

1 SELECT * FROM sys.[syscacheobjects]

 

 

重編譯的發生場景


但是有些時候,SQLSERVER為了確保返回正確的值,或者有性能上的顧慮,有意不重用緩存在記憶體里的執行計劃,而現場編譯一份。

這種行為,被稱為重編譯(recompile)。下麵是比較常見的會發生重編譯的情形:

 

1、當指令或者批處理所涉及的任何一個對象(表格或者視圖)發生了架構(schema)變化

例如,在表或者視圖上添加或刪除了一個欄位,添加或者刪除了一個索引,在表上添加或者刪除了一個約束條件(constraints)等。

定義發生了變化,原來的執行計劃就不一定正確了,當然要重編譯

 

2運行過sp_recompile

當用戶在某個存儲過程或者觸發器上運行過sp_recompile後,下一次運行他們就會發生一次重編譯。

如果用戶在某個表或者視圖上運行了sp_recompile,那麼所有引用到這張表(或者視圖)的存儲過程在下一次運行前,都要做重編譯

 

3、有些動作會清除記憶體里的所有執行計劃,迫使大家都要做重編譯

例如,下列動作會清除整個SQLSERVER伺服器緩存的所有執行計劃:

(1)Detach一個資料庫

(2)對資料庫做了升級,在新的伺服器上,會發生執行計劃清空

(3)運行了DBCC freeproccache

(4)運行了reconfigure語句

(5)運行了alter database..collate語句修改了某個資料庫的字元集(collation)

 

下列動作會清除SQLSERVER伺服器緩存的某個資料庫的執行計劃:

DBCC FLUSHPROCINDB

清除SQL Server 2000伺服器記憶體中的某個資料庫的存儲過程緩存內容

1 DECLARE @a INT
2 SELECT @a=DB_ID('gposdb')
3 DBCC flushprocindb(@a)

ALTER DATABASE ...MODIFY NAME語句

ALTER DATABASE ...SET ONLINE語句

ALTER DATABASE...SET OFFLINE語句

ALTER DATABASE...SET EMERGENCY語句

DROP DATABASE 語句

當一個資料庫自動關閉時

DBCC CHECKDB語句結束時

 

4、當下麵這些SET 開關值變化後,先前的那些執行計劃都不能重用

ansi_null_dflt_off,

ansi_null_dflt_on,

ansi_nulls,

_ansi_padding

ansi_warnings,

arithabort,

concat_null_yields_null,

datefirst,dateformat,

forceplan,

language,

no_browsetable,

numeric_roundabort,

quoted_identifier

這是因為這些SET開關會影響語句的執行的行為,甚至帶來不同的結果。他們發生變化了,SQLSERVER就要根據新的設置重做執行計劃

 

5、當表格或者視圖上的統計信息發生變化後

當統計信息被手動更新後,或者SQLSERVER發現某個統計信息需要自動更新時,SQLSERVER會對所涉及的語句都做重編譯

 

需要說明的是,在SQLSERVER里,執行計劃重用並不一定是一件好事,而編譯/重編譯也不一定是一件壞事。

計劃重用可以幫助SQLSERVER節省編譯時間,對降低CPU使用率和減少阻塞都有好處,但是缺點是每次重用的計劃並不一定是最合適的計劃。

參數嗅探parameter sniffing就是典型的計劃重用帶來的負效應。編譯和重編譯當然能給當前運行的語句帶來儘可能準確執行計劃,

但是對於經常運行的語句,尤其是一些執行速度比較快的語句,可能其編譯時間占最後總時間的相當大比例。這對資源來講是一個很大的浪費 

一般來說,SQLSERVER能夠很好地在編譯與重編譯之間做平衡,大部分情況下沒什麼問題的。


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

-Advertisement-
Play Games
更多相關文章
  • bootstrap scrollspy && bootstrap dropdown ...
  • 目前接觸到的報文格式有三種:xml 、定長報文、變長報文 。 此處只做簡單介紹,日後應該會深入學習到三者之間如何解析,再繼續更新。——2016.9.23 XML XML 被設計用來傳輸和存儲數據。 HTML 被設計用來顯示數據。 XML 僅僅是純文本 XML 沒什麼特別的。它僅僅是純文本而已。有能力 ...
  • table標簽製作表格代碼繁瑣,且不方便後期代碼維護。 li標簽加上css的浮動樣式可以製作多種樣式的表格。 代碼如下: <ul id="ttttt" style="width:404px;text-align:center;line-height:30px;border-left:1px soli ...
  • 當我們的網頁需要插入很多圖片的時候,為了美觀,我們可以選擇用瀑布流的方法插入圖片 首先我們在body裡面放入我們需要展示的圖片 <div id="box"> <div class="dinwei"> <div class="pic"> <img src="image/1.jpg"> </div> < ...
  • 好一段時間沒有更新博文了。剛學習完JS基礎知識後,也進入到了JQ的學習。為了能熟練掌握JQ的使用,最好的方法就是反覆多練,講JQ中的API的每個知識點都練習一遍。如果能做到這個,那麼對JQ就沒那麼陌生了。這一天,先將JQ中的選擇器的每個點熟悉一遍。註:記得先將JQ庫引入,並且<script></sc ...
  • 前幾天寫一個頁面 發現寬度為900px的div居然放不下3個寬度為300px的內聯元素li,只好改用了float:left來佈局。後來上網一查,才知道inline-block是有預設間距的,預設間距為4px,並且inline也是有預設間距。現在就來盤點一些解決inline-block元素和inlin ...
  • The Write Less , Do More ! jQuery選擇器 1. #id : 根據給定的ID匹配一個元素 結果: 這是第一個p標簽 這是第二個p標簽 2. element : 根據給定的元素標簽名匹配所有元素 結果: 這是div標簽1 這是div標簽2 這是p標簽 3. .class ...
  • 前面的話 前面分別介紹了拖拽模擬和磁性吸附,當可視區域記憶體在多個可拖拽元素,就出現碰撞檢測的問題,這也是javascript動畫的一個經典問題。本篇將詳細介紹碰撞檢測 原理介紹 碰撞檢測的方法有很多,接下來使用九宮格分析法 假設黃色元素要與紅色元素進行碰撞。將紅色元素所處的區域分為9部分,自身處於第 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...