国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > SQL Server > 正文

SQL Server里簡單參數(shù)化的痛苦

2024-08-31 00:54:02
字體:
來源:轉載
供稿:網(wǎng)友
SQL Server里簡單參數(shù)化的痛苦

在今天的文章里,我想談下對于即席SQL語句(ad-hoc SQL statements),SQL Server使用的簡單參數(shù)化(Simple Parameterization)的一些特性和副作用。首先,如果你的SQL語句包含這些,簡單參數(shù)化不會發(fā)生:

  • JOIN
  • IN
  • BULK INSERT
  • UNION
  • INTO
  • DISTINCT
  • TOP
  • GROUP BY
  • HAVING
  • COMPUTE
  • Sub Queries

一般來說,如果你處理所謂的安全執(zhí)行計劃(Safe Execution Plan),SQL Server自動參數(shù)化你的SQL語句:不管提供的參數(shù)值,查詢總必須通向一樣的執(zhí)行計劃。如果你的執(zhí)行計劃里有書簽查找,這就是不可能的例子。因為臨界點定義了是否進行書簽查找還是全表/聚集索引掃描。

自動參數(shù)化并不那么酷!

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

 1 -- Create a simple table 2 CREATE TABLE Orders 3 ( 4     Col1 INT IDENTITY(1, 1) PRIMARY KEY NOT NULL, 5     Price DECIMAL(18, 2) 6 ) 7 GO 8  9 -- This query gets auto parametrized, because it is a simple query with a safe (consistent) plan10 SELECT * FROM Orders11 WHERE Price = 5.7012 GO13 14 -- Analyze the Plan Cache15 SELECT16     st.text, 17     qs.execution_count, 18     cp.cacheobjtype,19     cp.objtype,20     cp.*,21     qs.*, 22     p.* 23 FROM sys.dm_exec_cached_plans cp24 CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) p25 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st26 LEFT JOIN sys.dm_exec_query_stats qs ON qs.plan_handle = cp.plan_handle27 WHERE st.text LIKE '%Orders%'28 GO

然后當你查看計劃緩存時,你會看到SQL Server能為你自動參數(shù)化SQL語句:

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

但什么是選擇的作為參數(shù)的數(shù)據(jù)類型?最小可能的那個!在這里是NUMERIC(3,2)!如果現(xiàn)在你執(zhí)行下列2個查詢:

1 -- Execute a slightly different query2 SELECT * FROM Orders3 WHERE Price = 8.704 GO5 6 -- Execute a slightly different query7 SELECT * FROM Orders8 WHERE Price = 124.509 GO

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

-- Execute a slightly different querySELECT * FROM OrdersWHERE Price = 1204.50GO

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

 1 -- Clear the Plan Cache 2 DBCC FREEPROCCACHE 3 GO 4  5 -- Execute a slightly different query 6 SELECT * FROM Orders 7 WHERE Price = 1204.50 8 GO 9 10 -- Execute a slightly different query11 SELECT * FROM Orders12 WHERE Price = 124.5013 GO14 15 -- Execute a slightly different query16 SELECT * FROM Orders17 WHERE Price = 8.7018 GO

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

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

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

 1 -- Create another table to demonstrate this problem 2 CREATE TABLE Orders3 3 ( 4     Col1 INT IDENTITY(1, 1) PRIMARY KEY NOT NULL, 5     Col2 VARCHAR(100) 6 ) 7 GO 8  9 -- Clears the Plan Cache10 DBCC FREEPROCCACHE11 GO12 13 -- A VARCHAR/CHAR column is always auto parametrized to a VARCHAR(8000)14 SELECT * FROM Orders315 WHERE Col2 = 'Woody'16 GO17 18 -- A VARCHAR column is always auto parametrized to a VARCHAR(8000)19 SELECT * FROM Orders320 WHERE Col2 = 'Tu'21 GO

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

小結

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

感謝關注!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 彭水| 甘德县| 兴仁县| 来安县| 普陀区| 巴马| 台南市| 内黄县| 利川市| 安陆市| 叶城县| 宜良县| 遂川县| 珲春市| 新民市| 山阴县| 黄梅县| 柳河县| 黄山市| 绥棱县| 郁南县| 华容县| 吕梁市| 曲阳县| 渑池县| 新民市| 永康市| 高邮市| 博爱县| 开封县| 南投县| 霍山县| 姚安县| 丰镇市| 胶州市| 南丹县| 宜丰县| 施秉县| 新竹县| 瑞昌市| 绥阳县|