SQL引數化查詢的另乙個理由 命中執行計畫

2022-09-28 08:30:12 字數 2738 閱讀 6253

1概述

sql語言的本質就是一串偽**,表達的是做什麼,而不是怎麼做的意思。如其它語言一樣,sql語句需要編譯之後才能執行,所以每一條sql是需要通過編譯器解釋才能執行的(在這之間還要做sql的優化)。而這些步驟都是需要執行成本,所以在資料庫中有乙個叫做執行計畫的東西,編譯器會將編譯過後的sql存入執行計畫當中,當遇到同樣的sql時,就直接呼叫執行計畫來執行,而不需要再次編譯。

通過對上面執行計畫的認識,為了提高資料庫執行的效率,我們需要盡可能的命中執行計畫,這樣就可以節省執行時間。

2相關sql

2.1檢視當前資料庫中所有的執行計畫:

複製** **如下:

select cp.usecounts as '使用次數'

,objtype as '型別'

,st.[text] as 'sql文字'

,plan_handle as '計畫控制代碼'

from sys.dm_exec_cached_plans cp

cross apply sys.dm_exec_sql_text(plan_handle) as st

where st.text not like '%sys%'

2.2刪除執行計畫

複製** **如下:

--刪除所有計畫

dbcc freeproccache

2.3測試指令碼(建立員工表,並向其插入1000條資料)

複製** **如下:

if exists (select * from sys.objects where object_id = object_id(n'[dbo].[employee]'))

drop table [dbo].employee

go --人員表

create table dbo.employee

( id int,

name nvarchar(50)

); --插入測試資料

declare @i int=0,@endi int=1000;

while(@ibegin

set @i+=1;

insert dbo.employee(id,name) values(@i,'蔣大華'+cast(@i as nvarchar(20)));

end;

3測試執行計畫

先執行刪除所有執行計畫,然後執行select * from employee ,最後檢視執行計畫(2.1中的檢視執行計畫指令碼)如下圖

即sql server會為每一條sql建立乙個執行計畫,並將它快取起來

3.2 再執行一次sql: select * from employee,並檢視執行計畫

可以看到這個計畫的重用次數為2,即這個計畫被重用了;

程式設計客棧3.3 修改sql:select  * from employee(在select後多加乙個空格),執行並檢視執行計畫

結果又新新增乙個執行計畫,即sql server認為這是兩個不同的sql語句並分別建立了執行計畫;

4重用執行計畫——使用引數化查詢方法

4.1 未引數化sql

複製** **如下:

string selectcmdtext = string.format(@"select * from employee where name=''",」 蔣大華1」);

sqlhelper.executenonquery(sqlhelper.defaulconnectiontstring, system.data.commandtype.text, selectcmdtext, null);

檢視執行計畫:

即當執行乙個未引數化sql時,sql server需要先將其轉換成乙個引數sql並執行它。一共需要兩執行計畫

然後再執行下面的**(查詢的條件變了)

複製** **如下:

string selectcmdtext = string.format(@"select * from employee where name=''",」 蔣大華2」);

sqlhelper.executenonquery(sqlhelper.defaulconnectiontstring, system.data.commandtype.text, selectcmdtext, null);

檢視執行計畫

此時不需要再準備乙個準備的sql,但還是需要再產生乙個執行計畫,並快取下來;

4.2 引數化sql

複製** **如程式設計客棧下:

sqlparameter param = ;

string selectcmdtext = string.format(@"select * from employee where name=@name");

sqlhelper.executenonquery(sqlhelper.defaulconnectiontstring, system.data.commandtype.text, selectcmdtext, param);

輸入引數並執行,然後檢視執行計畫:

只需要乙個準備sql,然後www.cppcns.com,輸入不同的引數,並執行,再檢視執行計畫

重用執行計畫,perfect...

5總結總的來說,sql語句在執行時,會生成執行計畫並將它快取起來,我們可以通過提高使用快取中的執行計畫次數,來減少資料庫的壓力。而使用引數化的sql是乙個很好的選擇,引數化查詢的作用不僅只有防止sql注入,還可以提高快取中執行計畫程式設計客棧使用次數。

本文標題: sql引數化查詢的另乙個理由 命中執行計畫

本文位址:

SQL引數化查詢的另乙個理由 命中執行計畫

1概述 sql語言的本質就是一串偽 表達的是做什麼,而不是怎麼做的意思。如其它語言一樣,sql語句需要編譯之後才能執行,所以每一條sql是需要通過編譯器解釋才能執行的 在這之間還要做sql的優化 而這些步驟都是需要執行成本,所以在資料庫中有乙個叫做執行計畫的東西,編譯器會將編譯過後的sql存入執行計...

乙個函式作為另乙個函式的引數

函式的作為變數分裝到另一函式裡面 上面的函式是求乙個定義域能被3正處的數,首先可以想到的是0到100之間內能被3整除的數吧。這個應該很簡單,如下。這裡可以思考的是某個定義域,也就是說上面的i 0和i 100都應該是不確定的值,也就是變數,現在可以定義乙個函式,function checkout st...

SQL查詢 存在乙個表而不在另乙個表中的資料

a b兩表,找出id欄位中,存在a表,但是不存在b表的資料。a表總共13w資料,去重後大約3w條資料,b表有2w條資料,且b表的id欄位有索引。使用 not in 容易理解,效率低 執行時間為 1.395秒 a b兩表,找出id欄位中,存在a表,但是不存在b表的資料。a表總共13w資料,去重後大約3...