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

2021-09-06 05:35:36 字數 3379 閱讀 4299

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

stwhere st.text

notlike

'%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

@iint

=0,@endi

int=

1000

;while(@i

<

@endi

)begin

set@i+=1

;

insert dbo.employee(id,name) values(@i,'

蔣大華'

+cast(@i

asnvarchar(20

)));

end;

3測試執行計畫3.1 先執行刪除所有執行計畫,然後執行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,然後,輸入不同的引數,並執行,再檢視執行計畫

重用執行計畫,perfect...

5總結

總的來說,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...