引數化(三) 引數嗅探

2022-02-14 11:22:28 字數 1736 閱讀 7736

在之前的隨筆中我提到過引數嗅探,這是非常重要的概念。下面我們深入的研究一下引數嗅探…

首先我們知道批處理可以是引數化的或者非引數化。引數化的批處理計畫有兩種型別:「prepared」 或者「proc」。前者對應帶有至少乙個引數的sys.sp_executesql的執行,並且從t-sql批處理,或者應用程式通過ado.net等直接被執行的。後者的執行計畫對應乙個儲存過程。

引數嗅探在這兩種型別中是完全相同的。它的行為在兩種計畫中是完全一樣的。因此我們這裡不去討論型別,只關心引數化批處理本身的作用。

什麼是引數嗅探?

當批處理包含乙個或者多個引數時並且它需要優化(例如因為沒有該批處理執行計畫快取,或者只有不可用的計畫),優化器知道引數的值。意味著優化器可以使用引數值去估計計畫中每個步驟返回的行數。就好像引數的值被硬編碼到批處理的文字中。這就是引數嗅探。

這是很有用的,因為如果優化器不知道引數的值,它將被迫去猜測返回的行數。基於平均統計和其他使用的元資料來盡可能準確地猜測,但是大多數時候仍然與真實行數相去甚遠。錯誤的估計導致選擇低效的執行計畫並導致很差的效能。

例如,乙個批處理第一次被執行,首先編譯,因為對應計畫在計畫快取中沒有。在編譯時,由於有引數嗅探,引數的值將被用來生成執行計畫。當計畫被建立時,計畫被放在快取中用來重用。下次相同的批處理被執行時,雖然有可能用了不同的引數,但是快取中的計畫仍將被重用。當然,第二次執行的結果將基於引數的值。但是執行第二次的計畫是與第一次一樣的,這個計畫就是來自於第一次執行的引數。

如上圖。在引數化批處理的實際執行計畫的圖形表示中,檢視最外層的操作符屬性(通常是乙個select操作符),然後找到「parameter list」屬性。展開屬性時,將會看到每個引數編譯時和執行時的值。編譯時的值就是引數嗅探用來生成計畫的引數。執行時的值是實際在指定計畫中的引數。

實際上,第二次執行可能是效能很差的,因為優化器在兩次生成計畫時估計返回資料的行數可能是相差大的。這裡純粹是運氣,沒有更好地方式。執行計畫被引數的值決定,而我們不能控制它,因為不知道編譯何時放生。如果計畫對於大多數執行時很高效的,那麼一切ok,但是如果它不是呢?假使使用者用乙個很少使用的引數來執行儲存過程,這個引數值產生乙個執行計畫,並且對於指定該值作為引數的執行是非常高效的。但是其他引數時將會表現很糟糕。

因此問題來了:引數嗅探是好還是不好?

一如往常,答案就是:「看情況」。這取決於資料的分布。讓我們看一下之前用的儲存過程:

create procedure

marketing.usp_customersbycountry

( @country as nchar(2)

)asselect

id ,

name ,

lastpurchasedate

from

marketing.customers

where

country =@country;

go

這種情況下,使用引數@country,來過濾行customers表的行數。如果大多數國家有差不多的行數,而且大多數執行使用了這些國家,那麼引數嗅探是很好的事情,因為大多數情況執行計畫是適用的,並且比不帶引數嗅探的計畫要好(未知引數)。另一方面,如果國家的值的分布不是均勻的,那麼乙個國家編碼的引數很有可能對於其他國家的查詢計畫就是乙個糟糕的選擇,此時引數嗅探就是不好的事情了。

那麼我們在引數嗅探是否有益這件事情上能做什麼?下一章將介紹如何高效的使用引數嗅探。

再探函式引數

c函式的所有引數均以 傳值呼叫 方式進行傳遞。這意味著函式將獲得引數值的乙份拷貝,這樣函式可以放心修改這個拷貝值,而不必擔心會修改呼叫程式實際傳遞給它的引數。普通資料型別主要包括 如下面 所示 include void swap int x int y int main 我們原本是希望編寫乙個函式,...

實踐三 網路嗅探與協議分析

目錄解決辦法 1.在拿到這個任務之後,我去查詢如何去編寫乙個簡單的抓包工具,發現python有乙個抓包用的庫scapy和解析包用到的庫dpkt。於是我就打算使用python來進行編寫。下面是安裝這兩個庫的截圖 由於pip版本不能更新問題導致無法導入庫,將近耗費了我一整天的時間修復,頭大!2.我將 分...

web自動化 三 pytest 引數化

前言 環境 centons 7.6 python 3.6 chrome 80.0.3987.132 chromedriver 80.0.3987.16 selenium 3.14 自動化測試過程中,經常會出有些場景需要測試多種場景,例如 常見的登入頁面需要對賬號的型別,種類,長度等分別進行測試,引用...