首先說明一下SQL Server內存占用由哪幾部分組成。SQL Server占用的內存主要由三部分組成:數據緩存(Data Buffer)、執行緩存(Procedure Cache)、以及SQL Server引擎程序。SQL Server引擎程序所占用緩存一般相對變化不大,則我們進行內存調優的主要著眼點在數據緩存和執行緩存的控制上。本文主要介紹一下執行緩存的調優。數據緩存的調優將在另外的文章中介紹。
對於減少執行緩存的占用,主要可以通過使用參數化查詢減少內存占用。
1、使用參數化查詢減少執行緩存占用
我們通過如下例子來說明一下使用參數化查詢對緩存占用的影響。為方便試驗,我們使用了一台沒有其它負載的SQL Server進行如下實驗。
下面的腳本循環執行一個簡單的查詢,共執行10000次。
首先,我們清空一下SQL Server已經占用的緩存:
dbcc freeproccache
然後,執行腳本:
復制代碼 代碼如下:
DECLARE @t datetime
SET @t = getdate()
SET NOCOUNT ON
DECLARE @i INT, @count INT, @sql nvarchar(4000)
SET @i = 20000
WHILE @i <= 30000
BEGIN
SET @sql = 'SELECT @count=count(*) FROM P_Order WHERE MobileNo = ' + cast( @i as varchar(10) )
EXEC sp_executesql @sql ,N'@count INT OUTPUT', @count OUTPUT
SET @i = @i + 1
END
PRINT DATEDIFF( second, @t, current_timestamp )
輸出:
DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。
11
使用了11秒完成10000次查詢。
我們看一下SQL Server緩存中所占用的查詢計劃:
Select Count(*) CNT,sum(size_in_bytes) TotalSize
From sys.dm_exec_cached_plans
查詢結果:共有2628條執行計劃緩存在SQL Server中。它們所占用的緩存達到:
92172288字節 = 90012KB = 87 MB。
我們也可以使用dbcc memorystatus 命令來檢查SQL Server的執行緩存和數據緩存占用。
執行結果如下:
執行緩存占用了90088KB,有2629個查詢計劃在緩存裡,有1489頁空閒內存(每頁8KB)可以被數據緩存和其他請求所使用。
有12875頁空閒內存(每頁8KB)可以被數據緩存所使用。
通過緩存計劃的plan_handle可以查詢到該執行計劃詳細信息,包括所對應的SQL語句:
SELECT TOP 100 usecounts,
objtype,
p.size_in_bytes,
[sql].[text]
FROM sys.dm_exec_cached_plans p
OUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sql
ORDER BY usecounts
我們可以選擇針對那些執行計劃占用較大內存、而被重用次數較少的SQL語句進行重點分析。看其調用方式是否合理。另外,也可以對執行計劃被重復使用次數較多的SQL語句進行分析,看其執行計劃是否已經經過優化。進一步,通過對查詢計劃的分析,還可以根據需要找到系統中最占用IO、CPU時間、執行次數最多的一些SQL語句,然後進行相應的調優分析。篇幅所限,這裡不對此進行過多介紹。讀者可以查閱聯機叢書中的:sys.dm_exec_query_plan內容得到相關幫助。
附:
1:關於DBCC MEMORY,可以查看微軟的知識庫: http://support.microsoft.com/kb/907877/EN-US
2:關於sys.dm_exec_cached_plans和sys.dm_exec_sql_text,請參閱聯機叢書。