檢查 SQL Server 審計隊列上的索引碎片
我已經閱讀了這篇出色的文章http://rusanu.com/2010/03/09/dealing-with-large-queues/,並且由於空間不足的問題,服務代理似乎遇到了同樣的問題在數據庫上關閉,sys.transmission_queue 表增長到大約 4000 萬條記錄。重新打開代理會顯著增加 tempdb 的大小,現在我想知道我的服務隊列是否正在遭受索引碎片的困擾。
我通常會使用 dm_db_index_physical_stats 來檢查索引統計資訊,但這不適用於隊列,那麼我如何找到內部表上的索引統計資訊,或者我什至可以在 SQL Server 2005 中這樣做嗎?
我對此進行了深入研究,看起來 SQL Server 團隊竭盡全力防止內部表統計資訊通過 DMF 和 DMV 公開。
我不能說我責怪他們,因為隊列之類的實現總是會發生變化,但這並不能幫助您解決問題。我明白為什麼在這種情況下很難在公開元數據和公開實現細節之間取得平衡。
無論如何,讓我們玩一些事情,看看會發生什麼。
如果我抓住一個
object_id
fromsys.internal_tables
並將其插入sys.dm_db_index_physical_stats
(顯而易見的事情),就會發生一些有趣的事情——在 2005 年,你得到一個空的結果集和一個 16 級錯誤(msg 2561,狀態 10);在 2008 R2 上,您只會得到一個沒有錯誤的空結果集。相反,如果您在 2005 上輸入一些隨機數,您會得到相同的錯誤,而在 2008 R2 上,您現在會得到不同的 16 級錯誤(消息 2573,狀態 40)。這告訴我,有一些內部檢查專門用於處理
sys.dm_db_index_operational_stats
使用有效但非 user-table 呼叫此函式(並且可能是所有函式)的情況object_id
。(注意:OBJECT_ID
在帶有前綴的內部表名上使用該函式sys.
會返回結果。)既然“解決”了碎片化問題,我想我會嘗試同一時代的
DBCC DBREINDEX
其他東西—— .DBCC SHOWCONTIG
sys.dm_db_index_physical_stats
如果我從
sys.internal_tables
(同樣,以 為前綴sys.
)為其提供表名,它不會返回任何內容——沒有錯誤,只是令人不滿意DBCC execution completed. If DBCC printed error messages, contact your system administrator.
——同時給它一個隨機object_id
結果會導致 16 級錯誤(msg 2501,狀態 45)。這是一個非常清楚的跡象,表明程式碼中對這種情況進行了明確的檢查。我使用正常連接和 DAC 嘗試了所有這些,結果相同。出於好奇,我什至嘗試在單使用者模式下啟動伺服器並使用 DAC,但這並沒有改變任何東西。
入侵資源數據庫以轉儲 DMF 的定義除了內部
OPENROWSET
語法之外什麼也沒有產生,這並不是特別有用(雖然有點有趣)。當我侵入資源數據庫時,我還轉儲了內部程序集並使用 Reflector 查看裡面的內容,但這並沒有產生任何結果(但同樣有趣)。
無論如何,我認為唯一合理的辦法是按照文章的建議進行操作——
DBCC DBREINDEX
根據需要頻繁地執行已棄用的工作。這些統計數據沒有任何可見性,至少我找不到,至少對我來說,這些統計數據似乎被故意隱藏了。可悲的是,即使您可以編寫自己的算法,無證文件也會
DBCC IND
以與 相同的方式失敗DBCC SHOWCONTIG
,這真的太糟糕了,因為這可能會給您一個不錯的機會。作為一項學術練習,您可以使用 的輸出來完成DBCC PAGE
,但顯然這遠非實用(或有效)解決方案。