运用计划缓冲的建议
計(jì)劃緩沖的基本目的是通過(guò)重用執(zhí)行計(jì)劃來(lái)改進(jìn)性能。因?yàn)?#xff0c;確認(rèn)執(zhí)行計(jì)劃確實(shí)可重用很重要。因?yàn)榧聪樵?xún)的計(jì)劃可重用性效率低下,所以一般建議盡可能依賴(lài)預(yù)定義工作負(fù)載技術(shù)。為了確保計(jì)劃緩沖的高效實(shí)用,遵循以下建議。
- 明確地參數(shù)化查詢(xún)的可變部分;
- 使用存儲(chǔ)過(guò)程實(shí)現(xiàn)業(yè)務(wù)功能;
- 使用sp_executesql避免存儲(chǔ)過(guò)程維護(hù);
- 使用準(zhǔn)備/執(zhí)行模式避免重新發(fā)送查詢(xún)字符串;
- 避免即席查詢(xún);
- 對(duì)動(dòng)態(tài)查詢(xún)使用sp_executesql代替EXECUTE;
- 小心地參數(shù)化查詢(xún)的可變部分;
- 避免修改鏈接之間的環(huán)境設(shè)置;
- 避免查詢(xún)中對(duì)象的隱含解析;
一、明確地參數(shù)化查詢(xún)的可變部分
查詢(xún)一般運(yùn)行多次,每次運(yùn)行的唯一不同是可變部分的不同值。它們的計(jì)劃可以重用,但是,查詢(xún)的靜態(tài)和可變部分應(yīng)該分離。雖然SQL Server有簡(jiǎn)單參數(shù)化和強(qiáng)制參數(shù)化特性,但是它們有各種局限性。應(yīng)該始終使用標(biāo)準(zhǔn)的預(yù)定義工作負(fù)載結(jié)束明確地執(zhí)行參數(shù)化。
二、使用存儲(chǔ)過(guò)程實(shí)現(xiàn)業(yè)務(wù)功能
如果已經(jīng)明確地參數(shù)化查詢(xún),將它放置在存儲(chǔ)過(guò)程中可能帶來(lái)最好的可重用性。因?yàn)橹恍枰l(fā)送參數(shù)和存儲(chǔ)過(guò)程的名稱(chēng),所以網(wǎng)絡(luò)流量減少了。存儲(chǔ)過(guò)程預(yù)先編譯,它們運(yùn)行得比即席查詢(xún)快速。存儲(chǔ)過(guò)程還能為包含在存儲(chǔ)過(guò)程中的一組查詢(xún)維護(hù)單一的參數(shù)化計(jì)劃,而不是維護(hù)大量單獨(dú)查詢(xún)的小型計(jì)劃。這避免了計(jì)劃緩沖被單獨(dú)查詢(xún)的計(jì)劃充滿(mǎn)。
三、使用sp_executesql編程以避免存儲(chǔ)過(guò)程維護(hù)
如果考慮存儲(chǔ)過(guò)程所需的對(duì)象維護(hù),或者打算使用客戶(hù)端生成的查詢(xún),則使用sp_executesql將查詢(xún)作為預(yù)定義工作負(fù)載提交。和存儲(chǔ)過(guò)程模式不同,sp_executesql不在數(shù)據(jù)庫(kù)中創(chuàng)建持續(xù)性對(duì)象。sp_executesql適合執(zhí)行單一的查詢(xún)或小型批查詢(xún)。在存儲(chǔ)過(guò)程中實(shí)現(xiàn)完整的業(yè)務(wù)員邏輯還可使用sp_executesql作為一個(gè)大的查詢(xún)串提交。但是,隨著業(yè)務(wù)邏輯復(fù)雜性的增加,為整個(gè)邏輯創(chuàng)建并維護(hù)一個(gè)查詢(xún)字符串將變得困難。
四、實(shí)現(xiàn)準(zhǔn)備/執(zhí)行模式以避免重傳查詢(xún)字符串
sp_executesql需要在每次重新執(zhí)行時(shí)通過(guò)網(wǎng)絡(luò)發(fā)送查詢(xún)字符串。它還需要服務(wù)器端查詢(xún)字符串匹配,以確認(rèn)對(duì)應(yīng)執(zhí)行計(jì)劃在過(guò)程緩沖中的開(kāi)銷(xiāo)。在ODBC或OLEDB(OLEDB.NET)應(yīng)用程序中,可以使用準(zhǔn)備/執(zhí)行模式以避免在多次執(zhí)行中重傳查詢(xún)字符串,因?yàn)橹恍枰峤挥?jì)劃句柄和參數(shù)。
在準(zhǔn)備/執(zhí)行模式中,因?yàn)橛?jì)劃句柄返回給應(yīng)用程序,該計(jì)劃可以被其他用戶(hù)連接重用--這并不僅限于創(chuàng)建該計(jì)劃的用戶(hù)。
五、避免即席查詢(xún)
不要使用即席查詢(xún)?cè)O(shè)計(jì)新的應(yīng)用程序。為即席查詢(xún)創(chuàng)建的執(zhí)行計(jì)劃不能在查詢(xún)以不同的可變部分值重新提交時(shí)重用。盡管SQL Server有簡(jiǎn)單參數(shù)化和強(qiáng)制參數(shù)化特性來(lái)隔離查詢(xún)的可變部分,但因?yàn)镾QL Server在參數(shù)化中的保守,這個(gè)特性只限于簡(jiǎn)單查詢(xún)。為了更好的計(jì)劃可重用性,將查詢(xún)作為預(yù)定義工作負(fù)載提交。
六、對(duì)于動(dòng)態(tài)查詢(xún)sp_executesql優(yōu)于EXECUTE
在存儲(chǔ)過(guò)程或數(shù)據(jù)庫(kù)應(yīng)用程序中動(dòng)態(tài)生成的SQL查詢(xún)字符串應(yīng)該使用sp_executesql而不是EXECUTE命令執(zhí)行。EXECUTE命令不允許查詢(xún)的可變部分明確地參數(shù)化。
如執(zhí)行以下語(yǔ)句:
DECLARE @n VARCHAR(3) SET @n = '678' DECLARE @sql VARCHAR(MAX) SET @sql = 'SELECT * FROM PersonTenThousand INNER JOIN Province ON PersonTenThousand.PId = Province.Id WHERE PersonTenThousand.Id = ' + @n + '' EXECUTE (@sql)生成的是即席計(jì)劃:
而如果換成:
DECLARE @n NVARCHAR(3) SET @n = 776 DECLARE @sql NVARCHAR(MAX),@param NCHAR(6) SET @sql = 'SELECT * FROM PersonTenThousand INNER JOIN Province ON PersonTenThousand.PId = Province.Id WHERE PersonTenThousand.Id = @1' SET @param = N'@1 INT' EXECUTE sp_executesql @sql,@param,@1 = @n結(jié)果如下:
我們看到,結(jié)果中生成了一個(gè)參數(shù)計(jì)劃。
七、小心地參數(shù)化查詢(xún)的可變部分
在把查詢(xún)的可變部分轉(zhuǎn)換為參數(shù)時(shí)要小心。一些變量的取值范圍可能急劇變化,以致某個(gè)計(jì)劃的取值范圍可能不適合于其他值,這可能導(dǎo)致參數(shù)嗅探。要根據(jù)情況的需要進(jìn)行處理。
八、不要允許查詢(xún)中對(duì)象的隱含解析
SQL Server允許在不同的架構(gòu)(Schema)下創(chuàng)建多個(gè)相同名稱(chēng)的數(shù)據(jù)庫(kù)對(duì)象。
例如,表t1可以使用兩個(gè)不同架構(gòu)(u1和u2)在單獨(dú)的所有者下創(chuàng)建。大部分系統(tǒng)中默認(rèn)的所有者是dbo(數(shù)據(jù)庫(kù)所有者)。
如果用戶(hù)u1查詢(xún):
SELECT * FROM t1 WHERE c1 = 1SQL Server首先嘗試查詢(xún)用戶(hù)u1默認(rèn)架構(gòu)下是否存在表t1。如果沒(méi)有,則嘗試查找dbo用戶(hù)的表t1是否存在。這種隱含解析使用戶(hù)u1可以在不同的架構(gòu)下創(chuàng)建表t1的另一個(gè)實(shí)例,并且臨時(shí)性訪(fǎng)問(wèn)它(使用相同的應(yīng)用程序代碼)而不影響其他用戶(hù)。
在生產(chǎn)服務(wù)器上,建議使用架構(gòu)所有者并且避免隱含解析。否則,使用隱含解析在生產(chǎn)服務(wù)器上將增加如下的開(kāi)銷(xiāo):
- 確認(rèn)對(duì)象需要更多的時(shí)間;
- 降低計(jì)劃緩沖可重用性的效率;
?
總結(jié)
- 上一篇: 分享3一个博客HTML5模板
- 下一篇: js返回上一页并刷新代码整理 转