天天看點

SQL Server裡簡單參數化的痛苦自動參數化并不那麼酷!小結

JOIN

IN

BULK INSERT

UNION

INTO

DISTINCT

TOP

GROUP BY

HAVING

COMPUTE

Sub Queries

如果SQL Server能自動參數化你的SQL語句,你還是要考慮下SQL Server引入的自動參數化SQL語句的一些副作用。我們來看一個具體的例子。下列查詢建立一個表,執行一個會被SQL Server自動參數化的簡單SQL語句。

然後當你檢視計劃緩存時,你會看到SQL Server能為你自動參數化SQL語句:

(@1 numeric(3,2))SELECT * FROM [Orders] WHERE [Price]=@1

但什麼是選擇的作為參數的資料類型?最小可能的那個!在這裡是NUMERIC(3,2)!如果現在你執行下列2個查詢:

SQL Server能重用為第1個使用8.7值SQL語句的參數化SQL語句的執行計劃。但用124.50值的第2個SQL語句呢?對于這個SQL語句緩存的計劃不能被重用,因為124.50值不符合NUMERIC(3,2)。在這個情況下,SQL Server用NUMERIC(5,2)資料類型生成你SQL語句的新參數化版本。你剛用你的SQL語句的額外的參數化版本污染了你的計劃緩存!當你執行下列語句會變得更糟:

這個會再次給你新的用NUMERIC(6,2)資料類型的新參數化版本——計劃緩存裡另一個版本!當我展示這個行為的時候,很多人都建議我應該用逆序來執行剛才的SQL語句。我們通過首先清空計劃緩存來試下。

然後當你看計劃緩存時,沒有任何改變:SQL Server還生成了3個不同的參數化SQL語句——每次都用最小可能的資料類型。

SQL Server裡簡單參數化的痛苦自動參數化并不那麼酷!小結

你怎麼做沒有一點關系,即你執行你SQL語句的順序:在自動參數化期間,SQL Server總會選擇最小可能的資料類型。當你依賴SQL Server這個特性時,好好考慮下。

VARCHAR如何呢?SQL Server自動參數化包含字元值(例如VARCHAR)的SQL語句時,事情會好點。假設有下清單定義和下列2個查詢:

在這個情況下,SQL Server用VARCHAR(8000)生成1個自動參數化SQL語句——最大可能的資料類型。從剛才例子裡,這是你所期待的行為。有時SQL Server好事壞事同時做……

當你和簡單SQL語句打交道時,自動參數化可以非常棒。但如你在這個文章裡所見,你要知道SQL Server引入的副作用。另外SQL Server的簡單參數化特性還會提供你強制參數化(Forced Parameterization)功能,這個我會在以後的文章裡介紹。

感謝關注!