新聞中心
在這篇文章里,我將介紹怎樣編寫你的代碼來提高緩存計(jì)劃的重用。了解當(dāng)有緩存計(jì)劃或重用一個(gè)已有的計(jì)劃時(shí)空格和注釋會(huì)產(chǎn)生怎樣的影響,這會(huì)幫助你降低你的應(yīng)用程序緩存的計(jì)劃數(shù)目。

創(chuàng)新互聯(lián)致力于網(wǎng)站建設(shè),網(wǎng)站制作設(shè)計(jì),營(yíng)銷網(wǎng)頁(yè)按需定制網(wǎng)站,外貿(mào)網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),微信小程序定制開發(fā),網(wǎng)站SEO優(yōu)化,網(wǎng)站設(shè)計(jì)制作案例豐富,是成都做網(wǎng)站公司和建站公司,歡迎咨詢。
探究緩存計(jì)劃
你在利用計(jì)劃緩存嗎?你是否很好地利用緩存計(jì)劃?你的應(yīng)用程序曾經(jīng)使用它們了嗎,它們是否被多次利用?你有沒有在同一時(shí)間在存儲(chǔ)過程緩存中對(duì)同一查詢具有多個(gè)緩存計(jì)劃?這些緩存計(jì)劃使用了多少空間?這些是你需要回答的問題,以確保你在優(yōu)化過程緩存以及減少你的應(yīng)用程序?qū)?chuàng)建的緩存計(jì)劃數(shù)目。你編寫你的T-SQL代碼時(shí)有些細(xì)微的地方需要注意,它會(huì)使得SQL Server為相同的T-SQL代碼去執(zhí)行額外的工作來編譯和緩存執(zhí)行計(jì)劃。
在SQL Server可以處理一個(gè)T-SQL批處理之前,它需要?jiǎng)?chuàng)建一個(gè)執(zhí)行計(jì)劃。為了使SQL Server創(chuàng)建一個(gè)執(zhí)行計(jì)劃,它必須首先消耗一些寶貴的資源,比如CPU來編譯一個(gè)T-SQL批處理。當(dāng)一個(gè)計(jì)劃編譯后,它被緩存起來,因此在你的應(yīng)用程序不止一次地調(diào)用相同的T-SQL語句時(shí)它可以被重用。如果你編寫你的T-SQL代碼來提高經(jīng)常執(zhí)行的T-SQL語句的緩存計(jì)劃的重用,那么你就能夠改進(jìn)你的代碼性能。
隨著SQL Server 2005的推出,微軟提供了一些你可以用來探究緩存計(jì)劃的DMV。通過使用這些DMV,你可以確認(rèn)一些關(guān)于緩存計(jì)劃的事情,下面是你可以確認(rèn)的事情的簡(jiǎn)短列表:
? 與一個(gè)緩存計(jì)劃相關(guān)的文本
? 一個(gè)緩存計(jì)劃執(zhí)行的次數(shù)
? 緩存計(jì)劃的規(guī)模
在后面我將告訴你怎樣使用DM來探究緩存計(jì)劃信息。
由于注釋或多余空格而使得有多個(gè)計(jì)劃
我相信你們所有人都有將代碼放到存儲(chǔ)過程中的想法。我們?yōu)榱舜a在一個(gè)應(yīng)用程序中或多個(gè)應(yīng)用程序間重用而這么做。但是,不是SQL Server執(zhí)行的所有代碼都包含在存儲(chǔ)過程中。一些應(yīng)用程序可能以順序T-SQL代碼來編寫的。如果你在編寫順序T-SQL代碼,那么你需要了解注釋你的代碼以及放置空格的方式可能會(huì)導(dǎo)致SQL Server為相同的T-SQL語句創(chuàng)建多個(gè)緩存計(jì)劃。
下面是一個(gè)T-SQL腳本的示例,它包含兩個(gè)不同的T-SQL語句:
- SELECT * FROM AdventureWorks.Production.Product
- GO
- SELECT * FROM AdventureWorks.Production.Product -- return records
- GO
如同你所看到的,我有兩個(gè)類似的T-SQL語句。兩者都將返回AdventureWorks.Production.Product表的所有記錄。那么你認(rèn)為如果你運(yùn)行這個(gè)代碼SQL Server會(huì)創(chuàng)建多少緩存計(jì)劃呢?為了回答這個(gè)問題,讓我使用SQL Server 2005和SQL Server 2008中提供的一對(duì)DMV來看看這個(gè)緩存計(jì)劃信息。為了查看這兩個(gè)T-SQL語句產(chǎn)生的計(jì)劃,我要運(yùn)行下面的代碼:
- DBCC FREEPROCCACHE
- GO
- SELECT * FROM AdventureWorks.Production.Product
- GO
- SELECT * FROM AdventureWorks.Production.Product -- return records
- GO
- SELECT stats.execution_count AS exec_count,
- p.size_in_bytes as [size],
- [sql].[text] as [plan_text]
- FROM sys.dm_exec_cached_plans p
- outer apply sys.dm_exec_sql_text (p.plan_handle) sql
- join sys.dm_exec_query_stats stats ON stats.plan_handle = p.plan_handle
- GO
在這個(gè)代碼中,我首先通過運(yùn)行DBCC FREEPROCCACHE命令來釋放這個(gè)過程緩存。這個(gè)命令刪除了內(nèi)存中所有編譯的執(zhí)行計(jì)劃。在這里關(guān)于這個(gè)命令我必須提一個(gè)忠告。你不要在一個(gè)生產(chǎn)環(huán)境中運(yùn)行DBCC FREEPROCCACHE命令。在你的生產(chǎn)環(huán)境中這么做會(huì)刪除你所有生成的緩存計(jì)劃,而這么做可能會(huì)嚴(yán)影響你的生產(chǎn)環(huán)境,因?yàn)榻?jīng)常使用的計(jì)劃會(huì)被重新編譯。在釋放了過程緩存之后,我執(zhí)行我的兩個(gè)不同的SELECT語句。最后,我將從一對(duì)不同的DMV獲得的信息連接在一起為這兩個(gè)SELECT語句返回一些緩存的計(jì)劃信息。當(dāng)我運(yùn)行這個(gè)時(shí),我從這個(gè)引用不同DMV的SELECT語句獲得下面的輸出:
- exec_count size plan_text
- -------------------- ----------- --------------------------------------------------------------------------
- 1 40960 SELECT * FROM AdventureWorks.Production.Product -- return records
- 1 40960 SELECT * FROM AdventureWorks.Production.Product
正如你從這個(gè)輸出看到的,我上面的兩個(gè)SELECT語句創(chuàng)建了兩個(gè)不同的緩存計(jì)劃,每個(gè)執(zhí)行了一次(exec_count數(shù)目)。這個(gè)的原因是這些SELECT語句并不完全一樣。一個(gè)SELECT語句稍稍有些不同,因?yàn)樗粋€(gè)注釋。還有,注意緩存計(jì)劃的大小,40,960字節(jié)!這占了很大一塊內(nèi)存,卻只是用于這樣一個(gè)微不足道的T-SQL語句。
所以你必須注意你是怎樣注釋你的代碼的。剪切和黏貼是復(fù)制你的應(yīng)用程序的一部分語句到另一部分的一個(gè)很好的方法,但是注意不要在你的類似的T-SQL語句前后或中間放置不同的注釋,這會(huì)導(dǎo)致多個(gè)計(jì)劃。
為相同的T-SQL命令生成多個(gè)緩存計(jì)劃的另一個(gè)方式是在你的T-SQL語句中包含一些額外的空格字符。下面是兩個(gè)類似的命令,除了空格不同:
- SELECT * FROM AdventureWorks.Production.Product
- GO
- SELECT * FROM AdventureWorks.Production.Product
- GO
正如你所看到的,第二個(gè)語句在FROM從句和對(duì)象名稱之間包含一對(duì)多余的空格。這個(gè)多余的空格將導(dǎo)致SQL Server優(yōu)化器認(rèn)為這兩個(gè)語句是不同的,并因此為這兩個(gè)語句創(chuàng)建不同的緩存計(jì)劃。在這里就很明顯第二個(gè)T-SQL語句中有多余的空格。但是如果你還在SELECT從句之前或語句之后添加一些其它字符,那么這個(gè)語句可能看起來是一樣的,因?yàn)槟悴荒芸闯鲞@個(gè)空格,但是SQL Server可以看到它,所以它由于這個(gè)多余的空格而創(chuàng)建多個(gè)緩存計(jì)劃。
當(dāng)SQL Server在查看一個(gè)批處理時(shí),它將它同已經(jīng)存在于存儲(chǔ)過程緩存中的計(jì)劃進(jìn)行對(duì)比。如果將要編譯的語句同一個(gè)已存在的緩存計(jì)劃是完全一樣的話,那么SQL Server不需要編譯并緩存這個(gè)計(jì)劃到內(nèi)存中。SQL Server這么做,以便它可以為類似語句重用計(jì)劃,如果這個(gè)計(jì)劃已經(jīng)存在于緩存中。為了優(yōu)化你的代碼,你要確保你盡可能地重用緩存計(jì)劃。
當(dāng)你在開發(fā)應(yīng)用程序代碼并在你的應(yīng)用程序中放置T-SQL代碼、并且不使用存儲(chǔ)過程時(shí),你需要注意確保你盡可能地做到最佳的計(jì)劃重用。在編寫代碼時(shí),如果我們想在我們的程序中不同的代碼塊中使用相同的代碼,那么我們就都使用剪切和黏貼。如同你在上面的例子中看到的,你在這么做時(shí)要小心。如果你在一個(gè)代碼塊中添加一些多余的空格,或可能是一個(gè)不同的注釋,那么你可能會(huì)得到不同的緩存計(jì)劃。
最大限度地提高性能和盡量減少內(nèi)存
要優(yōu)化你的代碼,你不僅需要擔(dān)心你寫的每條命令以及你的數(shù)據(jù)庫(kù)設(shè)計(jì),你還需要擔(dān)心你是否在類似的T-SQL語句中有多余的注釋和空格。如果你不留意類似的T-SQL語句周圍的細(xì)節(jié),你可能會(huì)導(dǎo)致SQL Server創(chuàng)建多個(gè)緩存計(jì)劃。對(duì)相同的T-SQL語句具有多個(gè)計(jì)劃會(huì)導(dǎo)致SQL Server工作更繁重,而且由于存儲(chǔ)這些緩存計(jì)劃而浪費(fèi)內(nèi)存。它可能看起來似乎并不是多么重要,但是作為T-SQL語句編寫人員,我們需要確保我們?cè)趦?yōu)化性能和盡量降低資源利用方面做到最好。其中一個(gè)方法就是確保你不會(huì)為相同的T-SQL語句緩存多個(gè)計(jì)劃。
【編輯推薦】
- SQL Server數(shù)據(jù)庫(kù)管理常用的SQL和T-SQL語句(1)
- 用T-SQL操作面試SQL Server開發(fā)人員(1)
- SQL Server 2008對(duì)T-SQL語言的增強(qiáng)(1)
- SQL Server 2005中的T-SQL
- T-SQL實(shí)用例句
文章題目:利用T-SQL代碼提高緩存效率 減少內(nèi)存消耗
本文鏈接:http://m.5511xx.com/article/cdjggeo.html


咨詢
建站咨詢
