1. 什么是SQLServer数据库碎片?
当数据库中有频繁的删除与更新操作时,数据库中的数据的存储位置就会变得不连续,成为碎片。这种现象称为数据库碎片。
数据库碎片会影响数据库的性能,造成数据库运行缓慢,甚至出现死锁等问题。
因此,对SQLServer数据库碎片进行优化是保证数据库稳定运行的必备措施。
2. 如何检测数据库碎片?
SQLServer提供了系统存储过程sp_msforeachtable,可以循环检测所有表的碎片情况。
2.1 使用sp_msforeachtable查找所有表的碎片信息
--创建临时表来存储碎片信息
CREATE TABLE #fraginfo
(
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(15, 8),
BestCount INT,
ActualCount INT,
LogicalFrag DECIMAL(15, 8),
ExtentFrag DECIMAL(15, 8)
)
--查询所有表的碎片信息,并将结果存放在临时表中
EXEC sp_msforeachtable 'INSERT INTO #fraginfo SELECT ''?'',OBJECT_ID(''?''),i.name AS indexname,i.index_id,ipl.*,ipf.avg_fragmentation_in_percent,ipf.fragment_count FROM sys.dm_db_index_physical_stats(DB_ID(),NULL,NULL,NULL,''LIMITED'') ipl JOIN sys.indexes i ON ipl.object_id=i.object_id AND ipl.index_id=i.index_id JOIN sys.dm_db_index_physical_fragmentation_stats(DB_ID(),NULL,NULL,NULL,''LIMITED'') ipf ON ipl.object_id=ipf.object_id AND ipl.index_id=ipf.index_id where avg_fragmentation_in_percent>30'
--查询临时表中的碎片信息,查看哪些表存在碎片,结果按照平均碎片率排序
SELECT * FROM #fraginfo ORDER BY Avg_fragmentation_in_percent DESC
DROP TABLE #fraginfo
从查询结果中可以看出哪些表存在碎片,以及碎片率的高低。
2.2 使用sp_spaceused查找表的碎片信息
如果想查询某一特定表的碎片信息,可以使用系统存储过程sp_spaceused。
sp_spaceused '表名'
执行该存储过程后,会返回该表的各项信息,包括碎片占用的空间。
3. 如何优化SQLServer数据库碎片?
优化SQLServer数据库碎片的方法主要有以下两种:
3.1 重构索引
重构索引可以消除碎片,提高数据库的性能。
重构索引的方法有两种,一种是在线重构索引,另一种是离线重构索引。
3.1.1 在线重构索引
在线重构索引不会影响数据库的正常运行,可以在不停止数据库服务的情况下实现。
在线重构索引可以使用以下命令进行:
ALTER INDEX 索引名 ON 表名 REORGANIZE
该命令将重构表中特定索引的碎片,达到优化数据库的目的。
3.1.2 离线重构索引
离线重构索引需要停止数据库服务,对整个数据库进行重构索引。
离线重构索引可以使用以下命令进行:
ALTER INDEX ALL ON 表名 REBUILD
该命令将重构表中所有索引的碎片,达到优化数据库的目的。
3.2 压缩数据
SQLServer 2008及以上版本提供了行压缩和页压缩两种方式,可以压缩数据库中的数据,进一步优化数据库性能。
行压缩和页压缩的方法大致相同,使用以下命令:
ALTER TABLE 表名 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = ROW|PAGE)
该命令将对表中的数据进行压缩,降低碎片率,提高数据库性能。
4. 总结
SQLServer数据库碎片是数据库性能下降的主要原因之一。
针对性的重构索引和压缩数据可以消除碎片,提高数据库的性能。