顯示指定的表的數(shù)據(jù)和索引的碎片信息。
DBCC SHOWCONTIG
[ ( { table_name | table_id | view_name | view_id }
[ , index_name | index_id ]
)
]
[ WITH { ALL_INDEXES
| FAST [ , ALL_INDEXES ]
| TABLERESULTS [ , { ALL_INDEXES } ]
[ , { FAST | ALL_LEVELS } ]
}
]
table_name | table_id | view_name | view_id
是要對(duì)其碎片信息進(jìn)行檢查的表或視圖。如果未指定,則對(duì)當(dāng)前數(shù)據(jù)庫(kù)中的所有表和索引視圖進(jìn)行檢查。若要獲得表或視圖 ID,請(qǐng)使用 OBJECT_ID 函數(shù)。
index_name | index_id
是要對(duì)其碎片信息進(jìn)行檢查的索引。如果未指定,則該語(yǔ)句對(duì)指定表或視圖的基索引進(jìn)行處理。若要獲得索引 ID,請(qǐng)使用 sysindexes。
WITH
指定由 DBCC 語(yǔ)句所返回的信息類型選項(xiàng)。
FAST
指定是否要對(duì)索引執(zhí)行快速掃描和輸出最少信息。快速掃描不讀取索引的葉或數(shù)據(jù)級(jí)頁(yè)。
TABLERESULTS
將結(jié)果顯示為帶有附加信息的行集。
ALL_INDEXES
顯示指定表和視圖的所有索引的結(jié)果(即使指定特定的索引)。
ALL_LEVELS
只能與 TABLERESULTS 選項(xiàng)一起使用。不能與 FAST 選項(xiàng)一起使用。指定是否為所處理的每個(gè)索引的每個(gè)級(jí)別產(chǎn)生輸出。如果未指定,將只對(duì)索引葉級(jí)或表數(shù)據(jù)級(jí)進(jìn)行處理。
當(dāng)指定 index_id 時(shí),DBCC SHOWCONTIG 語(yǔ)句將遍歷指定索引的葉級(jí)上的頁(yè)鏈。如果只指定 table_id,或者如果 index_id 為 0,則對(duì)指定表的數(shù)據(jù)頁(yè)進(jìn)行掃描。
DBCC SHOWCONTIG 確定表是否高度碎片化。在對(duì)表進(jìn)行數(shù)據(jù)修改(INSERT、UPDATE 和 DELETE 語(yǔ)句)的過(guò)程中會(huì)出現(xiàn)表碎片現(xiàn)象。由于這些修改通常并不在表的行中進(jìn)行平均分布,所以每頁(yè)的填滿狀態(tài)會(huì)隨時(shí)間而改變。對(duì)于掃描部分或全部表的查詢,這些表碎片會(huì)導(dǎo)致額外的頁(yè)讀取,這將防礙數(shù)據(jù)的并行掃描。
當(dāng)索引的碎片非常多時(shí),有兩種減少碎片的方法:
重新創(chuàng)建聚集索引將對(duì)數(shù)據(jù)進(jìn)行重新組織,其結(jié)果是使數(shù)據(jù)頁(yè)填滿。填滿程度可以使用 FILLFACTOR 選項(xiàng)進(jìn)行配置。這種方法的缺點(diǎn)是索引在除去/重新創(chuàng)建周期內(nèi)為脫機(jī)狀態(tài),并且操作屬原子級(jí)。如果中斷索引創(chuàng)建,則不會(huì)重新創(chuàng)建該索引。
DBCC INDEXDEFRAG 命令是聯(lián)機(jī)操作,所以索引只有在該命令正在運(yùn)行時(shí)才可用。而且可以在不丟失已完成工作的情況下中斷該操作。這種方法的缺點(diǎn)是在重新組織數(shù)據(jù)方面沒(méi)有聚集索引的除去/重新創(chuàng)建操作有效。
結(jié)果集中的"每頁(yè)上的平均可用字節(jié)數(shù)"和"平均頁(yè)密度(完整)"統(tǒng)計(jì)量指出索引頁(yè)的飽滿程度。"每頁(yè)上的平均可用字節(jié)數(shù)"的數(shù)字應(yīng)較小,而"平均頁(yè)密度(完整)"的數(shù)字應(yīng)較大。在指定 FILLFACTOR 選項(xiàng)的情況下除去和重新創(chuàng)建聚集索引可改善這些統(tǒng)計(jì)。另外,DBCC INDEXDEFRAG 命令在壓縮索引時(shí)考慮其 FILLFACTOR,這將改善這些統(tǒng)計(jì)。
索引的碎片級(jí)可以兩種方式確定:
注意:如果索引跨多個(gè)文件,這種確定碎片的方法不起作用。"擴(kuò)展盤區(qū)開(kāi)關(guān)數(shù)"的值應(yīng)盡可能接近于"掃描擴(kuò)展盤區(qū)數(shù)"的值。算出這一比率作為"掃描密度"的值,該值應(yīng)盡可能高。通過(guò)前面討論的減少碎片的任一種方法可改善該值。
"邏輯掃描碎片"和"擴(kuò)展盤區(qū)掃描碎片"(對(duì)于較小的擴(kuò)展盤區(qū))的值很好地表明了表的碎片級(jí)。這些值應(yīng)盡可能接近零(但 0% 到 10% 的值也可接受)。需要注意的是,如果索引跨多個(gè)文件,則"擴(kuò)展盤區(qū)掃描碎片"的值較大。兩種減少碎片的方法都可用于減少這些值。
下表描述結(jié)果集內(nèi)的信息。
統(tǒng)計(jì) | 描述 |
---|---|
掃描頁(yè)數(shù) | 表或索引的頁(yè)數(shù)。 |
掃描擴(kuò)展盤區(qū)數(shù) | 表或索引中的擴(kuò)展盤區(qū)數(shù)。 |
擴(kuò)展盤區(qū)開(kāi)關(guān)數(shù) | 遍歷索引或表的頁(yè)時(shí),DBCC 語(yǔ)句從一個(gè)擴(kuò)展盤區(qū)移動(dòng)到其它擴(kuò)展盤區(qū)的次數(shù)。 |
平均擴(kuò)展盤區(qū)上的平均頁(yè)數(shù) | 頁(yè)鏈中每個(gè)擴(kuò)展盤區(qū)的頁(yè)數(shù)。 |
掃描密度 [最佳值:實(shí)際值] | 最佳值是指在一切都連續(xù)地鏈接的情況下,擴(kuò)展盤區(qū)更改的理想數(shù)目。實(shí)際值是指擴(kuò)展盤區(qū)更改的實(shí)際次數(shù)。如果一切都連續(xù),則掃描密度數(shù)為 100;如果小于 100,則存在碎片。掃描密度為百分比值。 |
邏輯掃描碎片 | 對(duì)索引的葉級(jí)頁(yè)掃描所返回的無(wú)序頁(yè)的百分比。該數(shù)與堆集和文本索引無(wú)關(guān)。無(wú)序頁(yè)是指在 IAM 中所指示的下一頁(yè)不同于由葉級(jí)頁(yè)中的下一頁(yè)指針?biāo)赶虻捻?yè)。 |
擴(kuò)展盤區(qū)掃描碎片 | 無(wú)序擴(kuò)展盤區(qū)在掃描索引葉級(jí)頁(yè)中所占的百分比。該數(shù)與堆集無(wú)關(guān)。無(wú)序擴(kuò)展盤區(qū)是指:含有索引的當(dāng)前頁(yè)的擴(kuò)展盤區(qū)不是物理上的含有索引的前一頁(yè)的擴(kuò)展盤區(qū)后的下一個(gè)擴(kuò)展盤區(qū)。 |
平均每頁(yè)上的平均可用字節(jié)數(shù) | 所掃描的頁(yè)上的平均可用字節(jié)數(shù)。數(shù)字越大,頁(yè)的填滿程度越低。數(shù)字越小越好。該數(shù)還受行大小影響:行大小越大,數(shù)字就越大。 |
平均頁(yè)密度(完整) | 平均頁(yè)密度(為百分比)。該值考慮行大小,所以它是頁(yè)的填滿程度的更準(zhǔn)確表示。百分比越大越好。 |
如果指定表 ID 和 FAST 選項(xiàng),DBCC SHOWCONTIG 將返回僅包含以下列的結(jié)果集:
如果指定 TABLERESULTS,DBCC SHOWCONTIG 將返回在第一個(gè)表中描述的 8 列和以下的附加列。
統(tǒng)計(jì) | 描述 |
---|---|
ObjectName | 處理的表或視圖的名稱。 |
ObjectId | 對(duì)象名 ID。 |
IndexName | 處理的索引名。堆集的 IndexName 為 NULL。 |
IndexId | 索引的 ID。堆集的 IndexId 為 0。 |
Level | 索引的級(jí)別。級(jí)別 0 是索引的葉(或數(shù)據(jù))級(jí)。級(jí)別數(shù)隨著沿樹(shù)向上移動(dòng)到索引根而增加。堆集的級(jí)別為 0。 |
Pages | 組成某個(gè)索引級(jí)或整個(gè)堆集的頁(yè)數(shù)。 |
Rows | 某個(gè)索引級(jí)上的數(shù)據(jù)或索引記錄數(shù)。對(duì)于堆集,這是整個(gè)堆集中的數(shù)據(jù)記錄數(shù)。 |
MinimumRecordSize | 某個(gè)索引級(jí)或整個(gè)堆集中的最小記錄大小。 |
MaximumRecordSize | 某個(gè)索引級(jí)或整個(gè)堆集中的最大記錄大小。 |
AverageRecordSize | 某個(gè)索引級(jí)或整個(gè)堆集中的平均記錄大小。 |
ForwardedRecords | 某個(gè)索引級(jí)或整個(gè)堆集中的轉(zhuǎn)發(fā)記錄數(shù)。 |
Extents | 某個(gè)索引級(jí)或整個(gè)堆集中的擴(kuò)展盤區(qū)數(shù)。 |
指定 TABLERESULTS 和 FAST 時(shí),DBCC SHOWCONTIG 將返回如下列。
DBCC SHOWCONTIG 權(quán)限默認(rèn)授予 sysadmin 固定服務(wù)器角色或 db_owner 和 db_ddladmin 固定數(shù)據(jù)庫(kù)角色的成員以及表的所有者且不可轉(zhuǎn)讓。
下例顯示帶指定表名的表的碎片信息。
USE Northwind
GO
DBCC SHOWCONTIG (Employees)
GO
下例使用 OBJECT_ID 和 sysindexes 獲得 authors 表的 aunmind 索引的表 ID 和索引 ID。
USE pubs
GO
DECLARE @id int, @indid int
SET @id = OBJECT_ID('authors')
SELECT @indid = indid
FROM sysindexes
WHERE id = @id
AND name = 'aunmind'
DBCC SHOWCONTIG (@id, @indid)
GO
下例返回 pubs 數(shù)據(jù)庫(kù)中 authors 表的簡(jiǎn)略結(jié)果集。
USE pubs
DBCC SHOWCONTIG ('authors', 1) WITH FAST
下例顯示 pubs 數(shù)據(jù)庫(kù)中每個(gè)表上的每個(gè)索引的完整表結(jié)果集。
USE pubs
DBCC SHOWCONTIG WITH TABLERESULTS, ALL_INDEXES
下例顯示對(duì)數(shù)據(jù)庫(kù)中碎片數(shù)量在聲明的閾值之上的所有索引進(jìn)行碎片整理的簡(jiǎn)單方法。
/*Perform a 'USE <database name>' to select the database in which to run the script.*/相關(guān)文章
-- Declare variables
SET NOCOUNT ON
DECLARE @tablename VARCHAR (128)
DECLARE @execstr VARCHAR (255)
DECLARE @objectid INT
DECLARE @indexid INT
DECLARE @frag DECIMAL
DECLARE @maxfrag DECIMAL
-- Decide on the maximum fragmentation to allow
SELECT @maxfrag = 30.0
-- Declare cursor
DECLARE tables CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
-- Create the table
CREATE TABLE #fraglist (
ObjectName CHAR (255),
ObjectId INT,
IndexName CHAR (255),
IndexId INT,
Lvl INT,
CountPages INT,
CountRows INT,
MinRecSize INT,
MaxRecSize INT,
AvgRecSize INT,
ForRecCount INT,
Extents INT,
ExtentSwitches INT,
AvgFreeBytes INT,
AvgPageDensity INT,
ScanDensity DECIMAL,
BestCount INT,
ActualCount INT,
LogicalFrag DECIMAL,
ExtentFrag DECIMAL)
-- Open the cursor
OPEN tables
-- Loop through all the tables in the database
FETCH NEXT
FROM tables
INTO @tablename
WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
INSERT INTO #fraglist
EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS')
FETCH NEXT
FROM tables
INTO @tablename
END
-- Close and deallocate the cursor
CLOSE tables
DEALLOCATE tables
-- Declare cursor for list of indexes to be defragged
DECLARE indexes CURSOR FOR
SELECT ObjectName, ObjectId, IndexId, LogicalFrag
FROM #fraglist
WHERE LogicalFrag >= @maxfrag
AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0
-- Open the cursor
OPEN indexes
-- loop through the indexes
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
' + RTRIM(@indexid) + ') - fragmentation currently '
+ RTRIM(CONVERT(varchar(15),@frag)) + '%'
SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
' + RTRIM(@indexid) + ')'
EXEC (@execstr)
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag
END
-- Close and deallocate the cursor
CLOSE indexes
DEALLOCATE indexes
-- Delete the temporary table
DROP TABLE #fraglist
GO