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...