資源描述:
《執(zhí)行計(jì)劃的緩存和重新使用》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、執(zhí)行計(jì)劃的緩存和重新使用執(zhí)行計(jì)劃的緩存和重新使用.txt你無法改變別人,但你可以改變自己;你無法改變天氣,但你可以改變心情;你無法改變生命長度,但你可以拓展它的寬度。執(zhí)行計(jì)劃的緩存和重新使用SQLServer有一個(gè)用于存儲(chǔ)執(zhí)行計(jì)劃和數(shù)據(jù)緩沖區(qū)的內(nèi)存池。。內(nèi)存池中用于存儲(chǔ)執(zhí)行計(jì)劃的部分稱為過程緩存。執(zhí)行計(jì)劃包含:1.查詢計(jì)劃:執(zhí)行計(jì)劃的主體是一個(gè)重入的只讀數(shù)據(jù)結(jié)構(gòu),可由任意數(shù)量的用戶使用。這稱為查詢計(jì)劃。這里我的理解就是這個(gè)直讀數(shù)據(jù)結(jié)構(gòu)其實(shí)就是一個(gè)語句的框架或者說本體(比如select*fromkofwhereid=@id)。
2、2.執(zhí)行上下文:每個(gè)正在執(zhí)行查詢的用戶都有一個(gè)包含其執(zhí)行專用數(shù)據(jù)(如參數(shù)值)的數(shù)據(jù)結(jié)構(gòu)。此數(shù)據(jù)結(jié)構(gòu)稱為執(zhí)行上下文。這里我覺得應(yīng)該是執(zhí)行當(dāng)前SQL中你專有的一些數(shù)據(jù),可以放入查詢計(jì)劃中(比如你的語句elect*fromkofwhereid=33就是你的執(zhí)行上下文)執(zhí)行SQL語句與執(zhí)行計(jì)劃中的聯(lián)系:關(guān)系引擎將首先查看過程緩存中是否有用于同一SQL語句的現(xiàn)有執(zhí)行計(jì)劃。SQLServer將重新使用找到的任何現(xiàn)有計(jì)劃,從而節(jié)省重新編譯SQL語句的開銷。如果沒有現(xiàn)有執(zhí)行計(jì)劃,SQLServer將為查詢生成新的執(zhí)行計(jì)劃。執(zhí)行計(jì)劃的老化:什
3、么叫老化?就是沒用了,就會(huì)棄用它.那在SQLSERVER怎么樣去判斷老化的執(zhí)行計(jì)劃呢?每個(gè)查詢計(jì)劃和執(zhí)行環(huán)境都有相關(guān)的成本因子,可表明編譯結(jié)構(gòu)所需的費(fèi)用。這些數(shù)據(jù)結(jié)構(gòu)還有一個(gè)年齡字段。對(duì)象每由連接引用一次,其年齡字段便按編譯成本因子遞增。比如:1)如果查詢計(jì)劃的成本因子為8并且被引用了兩次,則其年齡變?yōu)?6。2)惰性寫入器進(jìn)程定期掃描過程緩存中的對(duì)象列表。然后,惰性寫入器減少每個(gè)對(duì)象的年齡字段,每掃描一次減少1。3)不斷重復(fù)1)2)步驟,不斷變化對(duì)象的年齡字段.再舉個(gè)例子:我的一個(gè)SQL語句成本因子為6.我第一次引用后他的年
4、齡變成6.惰性寫入器每2天掃描一次,6天后,它的年齡變成3(6-3).然后三天后我又連續(xù)調(diào)用2次,年齡又變成了15.說明它至少還30天可以不被調(diào)用.原因很簡單一旦對(duì)象的年齡字段為0是惰性寫入器進(jìn)程將釋放對(duì)象的條件之一,還有2個(gè)條件是:a.內(nèi)存管理器需要內(nèi)存而所有可用內(nèi)存都正在使用。b.對(duì)象在當(dāng)前沒有被連接引用。因?yàn)槊看我脤?duì)象時(shí)其年齡字段都會(huì)增加,所以經(jīng)常被引用的對(duì)象的年齡字段不會(huì)減為0,也不會(huì)從緩存老化掉。重新編譯執(zhí)行計(jì)劃:能夠達(dá)到重新編譯執(zhí)行計(jì)劃的因素有2種:一種是上面提到的執(zhí)行計(jì)劃的老化,另外一種就是數(shù)據(jù)庫中的某些更改
5、可能導(dǎo)致執(zhí)行計(jì)劃效率降低或無效.導(dǎo)致計(jì)劃無效的情況包括:1.對(duì)查詢所引用的表或視圖進(jìn)行更改(ALTERTABLE和ALTERVIEW)。2.對(duì)執(zhí)行計(jì)劃所使用的任何索引進(jìn)行更改。3.對(duì)執(zhí)行計(jì)劃所使用的統(tǒng)計(jì)信息進(jìn)行更新,該更新可能是從語句(如UPDATESTATISTICS)中顯示生成,也可能是自動(dòng)生成的。4.刪除執(zhí)行計(jì)劃所使用的索引。5.顯式調(diào)用sp_recompile。6.對(duì)鍵的大量更改(其他用戶對(duì)由查詢引用的表使用INSERT或DELETE語句所產(chǎn)生的修改)。7.對(duì)于帶觸發(fā)器的表,插入的或刪除的表內(nèi)的行數(shù)顯著增長。8.使用
6、WITHRECOMPILE選項(xiàng)執(zhí)行存儲(chǔ)過程。舉個(gè)例子:刪除執(zhí)行計(jì)劃所使用的索引就會(huì)改變執(zhí)行計(jì)劃createtabletest(idint,valueint)--建立索引createclusteredindexCL_SK_IDontest(id)inserttestvalues(1,2)inserttestvalues(2,3)select*fromtestwhereid=1--刪除索引dropindexCL_SK_IDontestselect*fromtestwhereid=1---------------按CTRL+L--
7、--------------------PS:語句級(jí)編譯的問題:在SQLServer2000中,只要批處理中的語句導(dǎo)致重新編譯,就會(huì)重新編譯整個(gè)批處理,無論此批處理是通過存儲(chǔ)過程、觸發(fā)器、即席批查詢,還是通過預(yù)定義的語句進(jìn)行提交。在SQLServer2005和更高版本中,只會(huì)重新編譯批處理中導(dǎo)致重新編譯的語句。語句級(jí)重新編譯有助于提高性能,因?yàn)樵诖蠖鄶?shù)情況下,只有少數(shù)語句導(dǎo)致了重新編譯并造成相關(guān)損失(指CPU時(shí)間和鎖)。因此,避免了批處理中其他不必重新編譯的語句的這些損失。參數(shù)化的問題:createtabletest(idi
8、nt,valueint)goinserttestvalues(1,2)inserttestvalues(2,3)select*fromtestwhereid=1select*fromtestwhereid=2這個(gè)例子的2句select語句目的是要讓SQLServer總是認(rèn)為語句實(shí)際生成了相