[英]How can I quickly detect and resolve SQL Server Index fragmentation for a database?
我遇到過這樣一種情況:隨着更多記錄的添加,我對許多SQL Server數據庫表的數據庫操作變得非常緩慢(單個插入到具有100萬條記錄的表的5s)。
我估計這可能是由於我的數據庫中表的碎片索引,因為我有許多表使用(並且需要使用)主鍵聚簇索引的uniqueidentifier類型。
我如何評估是否是這種情況,如果存在任何碎片問題,如何解決碎片問題(可能每次部署一次)?
我想要一個適用於SQL Server 2005及更高版本的解決方案(我在Azure數據庫(12.0.2000.8)中專門使用SQL Server)。
檢查表上的碎片百分比
SELECT a.index_id,
NAME,
avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages
FROM sys.Dm_db_index_physical_stats(Db_id('dbName'), Object_id('tableName'),
NULL,
NULL, NULL) AS a
INNER JOIN sys.indexes b
ON a.object_id = b.object_id
AND a.index_id = b.index_id
要修復碎片,請重建或重新組織表上的索引
ALTER INDEX ALL ON table_name REBUILD
要么
ALTER INDEX index_name ON table_name REBUILD
- 重組
ALTER INDEX ALL ON table_name REORGANIZE
要么
ALTER INDEX index_name ON table_name REORGANIZE
要么
DBCC DBREINDEX ('table_Name')
https://docs.microsoft.com/en-us/sql/relational-databases/indexes/reorganize-and-rebuild-indexes
由於您已經知道懷疑存在碎片的表,因此可以使用以下T-SQL語句來識別碎片。
要獲取數據庫的數據庫ID:
select name , database_id
from sys.databases
where name = 'Database_Name'
在表所屬的數據庫下運行這些查詢。
要獲取表的對象ID:
select * from sys.objects where name = 'Table_name'
要在表中查找碎片百分比:
select TableName=object_name(dm.object_id)
,IndexName=i.name
,IndexType=dm.index_type_desc
,[%Fragmented]=avg_fragmentation_in_percent ,dm.fragment_count ,dm.page_count ,dm.avg_fragment_size_in_pages
,dm.record_count ,dm.avg_page_space_used_in_percent from
sys.dm_db_index_physical_stats(14,420770742,null,null,'SAMPLED') dm
--Here 14 is the Database ID
--And 420770742 is the Object ID of the table
join sys.indexes i on dm.object_id=i.object_id and
dm.index_id=i.index_id order by avg_fragmentation_in_percent desc
如果索引的碎片超過20%,那么我們可以嘗試重建該索引:
ALTER INDEX Index_Name
ON [Database_name].[Table_Name] REBUILD
或 - 重建表中的所有索引
ALTER INDEX ALL ON [Database_name].[Table_Name]
REBUILD WITH (FILLFACTOR = 80)
或者 - 使用DBCC DBREINDEX
DBCC DBREINDEX ('[Database_name].[ Table_Name]')
DBCC DBREINDEX ('[Database_name].[ Table _Name]',
'Index_Name, 85)
如果碎片計數低於20%,您可以取消索引重建或ReOrg ..而只是更新該索引/表的統計信息。
要使用FULLSCAN在表上運行更新統計信息:
UPDATE STATISTICS [Database_Name].[Table_Name]
with FULLSCAN
更新索引的統計信息
UPDATE STATISTICS [Database_Name].[Table_Name] Index_Name
with FULLSCAN
我已將每個問題作為單獨的查詢給您,以便更好地了解正在執行的操作。 希望這可以幫助
這是一個在SQL Server 2005及更高版本中運行的SQL查詢解決方案,它將為您提供幫助
1)首先找到需要重建或重組的所有索引以減少碎片,然后
2)將結果的前五列的單個復制粘貼到新的查詢窗口(刪除列標題行),執行將解決大多數當前碎片問題的所有語句(重建/重組索引)在數據庫的所有表中。
注意:如果遇到權限錯誤,則可能需要確保定位在主模式中,並且用戶具有對數據庫的適當權限。
我將此查詢命名為: GetFragmentationOfIndexesAndFirst5ColumnsExecutedResolveFragmentation.sql
SELECT
'alter index' as 'reindex_part1',
'[' + dbindexes.[name] + ']' as 'Index',
'on' as 'reindex_part2',
'[' + dbtables.[name] + ']' as 'Table',
CASE WHEN indexstats.avg_fragmentation_in_percent > 30
THEN 'rebuild with (FILLFACTOR = 80)' ELSE 'reorganize' END as 'reindex_part3',
indexstats.avg_fragmentation_in_percent,
indexstats.page_count,
indexstats.alloc_unit_type_desc,
dbschemas.[name] as 'Schema'
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats
INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID()
AND indexstats.avg_fragmentation_in_percent > 5
ORDER BY indexstats.avg_fragmentation_in_percent desc
我必須相信我用於理解並最終實現此解決方案的兩個地方:
在數據庫中查找碎片的初始方法: https : //myadventuresincoding.wordpress.com/2013/05/27/sql-server-check-index-fragmentation-on-all-indexes-in-a-database/
如何解決數據庫中的碎片問題(並且應該通過重組索引來解決5%-30%碎片的准則,並且應該通過重建索引來解決30%+碎片): http : //www.passionforsql.com/how -to-檢查索引碎片式-SQL服務器/
編輯:我在上面的查詢中包含了with (FILLFACTOR = 80)
部分,因為在我的情況下,大多數碎片索引都在uniqueidentifier列上,不應該使用默認的FILLFACTOR為0(100%)進行索引,因為以這種方式使用它們將不可避免地再次快速導致碎片,因為由於無序創建uniqueidentifier,因此總是需要將插入放在其他行之間。 您當然可以更改粘貼值以刪除或更改適合您的表/索引的參數。
我還發現,在重建和重組索引之后,您將需要執行EXEC sp_updatestats
,以便統計信息可以趕上索引更改,而不必在將來的查詢中逐步執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.