效能調優5 執行計畫

2022-01-10 07:38:37 字數 3681 閱讀 5462

查詢優化器基於當前的統計資訊和引數,衡量開銷之後,選擇「最優」的執行計畫,需要注意的是,「最優」是相對的,優化器不可能窮舉所有的執行計畫來評估其開銷,這個「最優」的標準是對當前引數和當前的統計資訊來說的,優化器從生成的備選執行計畫中選擇開銷最小的。由於執行計畫的編譯和生成是很耗費資源和時間的,因此,sql server會把生成的任一執行計畫快取起來,以便重用。

由於關係表的資料和結構可能發生改變,資料更新會導致統計資訊過時,而之前的引數可能不具有代表性,使得已生成的執行計畫不能代表其他引數值,導致查詢效能低下。因此,應當監控執行計畫的效能,當發現引數嗅探問題時,應該及時修改**以重編譯;當發現統計資訊過期時,應及時更新統計資訊等。

sql server使用特定的快取機制,以重用第一次執行查詢時生成的執行計畫,總的來說,sql server內部有以下四種執行計畫快取機制:

對於adhoc查詢的快取,是sql server自動進行的,使用者不能干預,而後兩種是使用者可以干預的,使用者可以通過優化**來復用「模板化」的查詢。所謂模板化語句,是指除了個別的常量發生變化之外,語句主體不變,可以把變化的常量作為乙個引數,不變的語句主體作為乙個模板來處理,sql server優化器把這個模板編譯成執行計畫,傳入不同的引數會使用相同的執行計畫。

1,ad hoc查詢快取

對於任意乙個ad hoc查詢,sql server都會快取它的執行計畫,但是,只有當批處理語句的文字完全匹配時,才會復用已快取的執行計畫,完全匹配的處理過程是:

大量的ad hoc查詢快取會占用計畫快取的空間,這些快取可能只會被使用一次,以後再也不會被使用。如果資料庫系統中存在大量的一次性查詢語句,應設定server 級別的效能優化選項:optimize for ad hoc wrokloads。

「針對即席工作負載進行優化」是乙個server級別的效能優化選項,用於提高包含許多臨時批處理的工作負載的計畫快取的效率,如果把該選項設定為true,則資料庫引擎在首次編譯批處理時只保留計畫快取中的乙個存根,而不是儲存整個執行計畫。當再次呼叫該批處理時,資料庫引擎識別出該批處理在之前被執行過,進而從計畫快取中刪除該執行計畫的存根,並把完全編譯的執行計畫新增到計畫快取中。當非引數化的ad-hoc查詢較多時,可以避免計畫快取儲存過多的不會被復用的執行計畫。

2,引數化ad-hoc

sql server 自主決定是否把查詢中的常量作為引數來對待,除了常量不同之外,其他語句主體都相同,這就是這個查詢語句的模板,不同的引數使用相同的執行計畫。

例如,對於以下兩個查詢語句,除了常量1和2不同之外,其他語句都相同,

select id, name from dbo.users where id=1

select id, name from dbo.users where id=2

sql server對該語句做引數化處理,得到模板,只要語句符合該模板,優化器就復用已快取的執行計畫。

select id, name from dbo.users where id=@id
3,prepared 查詢快取

使用者使用sys.sp_executesql控制引數和模板,只要模板相同,而引數不同,都可以復用已快取的執行計畫。

4,儲存過程

使用者建立的儲存過程,在第一次執行時,編譯和生成執行計畫,並快取到計畫快取中,當下次呼叫相同的儲存過程,即使使傳遞的引數不同,sql server都會復用執行計畫。

引數嗅探是指在建立儲存過程,或者引數化查詢的執行計畫時,根據傳入的引數進行預估並生成執行計畫。sql server生成的執行計畫對當前引數來說是最優的,而對其他大多數引數來說,是非常低效的。有些時候,針對乙個查詢的第一次傳參,已經產生了乙個執行計畫,當後續傳參時,由於存在對應引數的資料分布等問題,導致原有的執行計畫無法高效地響應查詢請求,這就出現引數嗅探問題。

引數嗅探的本質是優化器根據引數來生成的執行計畫不是最優的,導致優化器在復用執行計畫時,語句的查詢效能變得十分低下。對於引數嗅探問題,必須重新生成執行計畫,可以使用語句重編譯,編譯提示(optimize for)等功能來避免。

sql server不會永久儲存計畫的快取,並且存在快取中的執行計畫也不會永久不變,每個計畫都會有乙個age值,當sql server探測到記憶體壓力時,會觸發lazy writer程序,用於清空所有的髒頁,釋放資料快取。當掃面到計畫快取時,會降低age值,當復用一次計畫時,會增加age值。當系統遇到記憶體壓力,或age值降到0時,執行計畫會被移除記憶體。

除了這兩個條件之外,當遇到下面的條件時,執行計畫一會被移除記憶體,被重新編譯:

在執行計畫執行過程中,執行計畫被重新編譯,是優化器根據表結構,索引結構和統計資訊做出優化的結構,目的是為了避免繼續使用不合適的執行計畫。

修改儲存過程,觸發器等模組(module)能夠使其執行計畫重新編譯,除此之外,還有其他方法,能夠強制重新編譯執行計畫

1,標記,下次重新編譯

使用該儲存過程,標記乙個執行模組(sp,trigger,user-defined function)在下次執行時,重新編譯執行計畫

sys.sp_recompile [

@objname = ]'

object

'

2,不復用執行計畫

在建立儲存過程時,使用with recompile 選項,在每次執行sp時,都重新編譯,使用新的執行計畫。

create

procedure

dbo.usp_procname

@parameter_name

varchar(30) =

'parameter_default_value

'with recompile

3,執行時重新編譯

在執行儲存過程時,重新編譯儲存過程的執行計畫

exec dbo.usp_procname @parameter_name='

parameter_value

'with recompile

4,語句級別的重新編譯

在sp中,使用查詢選項 option(recompile),只重新編譯該語句級別的執行計畫

select

column_name_list

from

dbo.tablename

option(recompile)

sql server在執行查詢之後,查詢提示(recompile)指示儲存引擎將計畫快取拋棄,在下次執行儲存過程時,強制查詢優化器重新編譯,生成新的執行計畫。在重新編譯時,sql server 優化器使用當前的變數值生成新的計畫快取。

優化器會根據查詢選擇執行計畫,選擇索引,表關聯演算法等,但是,當發現優化器選擇了低效的執行計畫時,可以使用hint來控制執行計畫,sql server提供了三種型別的hint:

1,查詢提示

使用option來設定查詢提示,

2,關聯提示

在 join關鍵字前面使用loop,merge和hash來控制關聯的演算法

3,表提示

在引用的表名後面,通過with()來設定表提示 table_name with(hints),

當使用索引時,使用 with(index(index_name))來設定,

調優 Nginx效能調優

一.nginx優化配置 1.主配置檔案優化 注 部分配置詳解 worker processes 8 nginx程序數,建議按照cpu數目來指定,一般為它的倍數。worker cpu affinity 00000001 00000010 00000100 00001000 00010000 00100...

jvm5 效能調優

知識 工具資料 經驗案例1 問題 經常有使用者反饋長時間出現卡頓的現象 處理思路 偶發,所以不會是sql問題 監控cpu 監控記憶體 發現fullgc頻繁,每次需要20 30s,停頓時間過長 總結 大物件過多,jvm記憶體設定的過大,老年代經常佔滿觸發fullgc,老年代記憶體過大每次fullgc時...

Spark效能調優 JVM調優

通過一張圖讓你明白以下四個問題 1.jvm gc機制,堆記憶體的組成 2.spark的調優為什麼會和jvm的調優會有關聯?因為scala也是基於jvm執行的語言 3.spark中oom產生的原因 4.如何在jvm這個層面上來對spark進行調優 補充 spark程式執行時 jvm堆記憶體分配比例 r...