文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SQL Server表空间碎片化回收怎么实现

2023-06-29 14:34

关注

这篇文章主要介绍了SQL Server表空间碎片化回收怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SQL Server表空间碎片化回收怎么实现文章都会有所收获,下面我们一起来看看吧。

1 锁片化的产生

1.1 产生碎片化的原因

在B-tree索引中,表数据按照聚集索引的排序进行物理存储,若聚集索引离散化比较严重,那么可能会出现较为严重的碎片化问题;

随着业务的DML操作,会伴随着数据页分裂的情况,这种情况下也会导致表空间碎片化问题;

大表通过delete清理无效历史数据,delete产生碎片化空间;

1.2 碎片化的影响

表空间碎片化越严重越容易影响对该表的查询效率,这是因为当表碎片化比较严重时,数据库根据执行计划扫描满足需求的数据页会扫描较多“无效页面”,导致查询操作需要更多的IO消耗。

1.3 定位碎片化

在SQL Server中,可以通过DBCC SHOWCONTIG的方式查看表空间碎片化的一些统计信息,具体语法如下:

--查看数据库中所有索引的碎片信息use ${数据库名}DBCC SHOWCONTIG WITH ALL_INDEXES --查看指定表的所有索引的碎片信息DBCC SHOWCONTIG (${表名}) WITH ALL_INDEXES   --查看指定表、指定索引的碎片信息DBCC SHOWCONTIG (${表名},${索引名})

通过sys.dm_db_index_physical_stats()查看索引碎片化

SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'db1'), OBJECT_ID(N'db1.dbo.users'), NULL, NULL , 'LIMITED');SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'db1'), OBJECT_ID(N'db1.dbo.users'), NULL, NULL , 'DETAILED');

重点关注:

通过统计信息查看数据库碎片化空间Top表信息

SELECT    db_name() as DbName,    t.NAME AS TableName,    s.Name AS SchemaName,    p.rows AS RowCounts,    SUM(a.total_pages) * 8 AS TotalSpaceKB,     CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS 总共占用空间MB,    SUM(a.used_pages) * 8 AS 总使用空间KB,     CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS 总使用空间MB,     (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS 碎片化空间KB,    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS 碎片化空间MBFROM     sys.tables tINNER JOIN          sys.indexes i ON t.OBJECT_ID = i.object_idINNER JOIN     sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_idINNER JOIN     sys.allocation_units a ON p.partition_id = a.container_idLEFT OUTER JOIN     sys.schemas s ON t.schema_id = s.schema_idWHERE     t.is_ms_shipped = 0    AND i.OBJECT_ID > 0GROUP BY     t.Name, s.Name, p.RowsORDER BY     总共占用空间MB desc

2 碎片化处理

由于表数据是根据聚集索引排序进行物理存储,所以当表碎片化比较严重时,可以通过对聚集索引的重新组织来进行碎片化空间回收,重建索引的方式也有比较多方式,主要如下:

2.1 删除并重建聚集索引

该方式其实就是将碎片化比较严重的表,先通过drop index删除其聚集索引,然后通过create index或者alter table重建聚集索引。该方式的特点是:

2.2 DROP_EXISTING

使用DROP_EXISTING进行重建索引,也是对聚集索引的删除重建,但是该方式在方法一的基础上做了一些优化:

基本语法:

CREATE INDEX ${index_name} ON T(${index_col})  WITH (DROP_EXISTING = ON)

2.3 DBCC DBREINDEX

DBCC DBREINDEX也是通过对索引的删除以及重建来实现碎片化回收。根据数据库版本(企业版or非企业版)以及索引类型(非聚集or聚集),该操作是可以实现在线或者离线操作。

基本语法:

-- 重建指定索引USE ${db_name};   GO  DBCC DBREINDEX ('${schema_name}.${table_name}', ${index_name},80);  GO-- 重建指定表全部索引USE ${db_name};   GO  DBCC DBREINDEX ('${schema_name}.${table_name}', ' ', 70);  GO

2.4 DBCC INDEXDEFRAG

该方式的实现逻辑与以上三种大有不同,DBCC INDEXDEFRAG并非完全重新组织整张表的b-tree结构:

DBCC INDEXDEFRAG按照索引键的逻辑顺序,通过压缩索引页里的行然后删除那些由此产生的不必要的碎片化数据页、删除完全碎片化数据页面的方式来进行碎片化空间的回收
该方式执行期间不阻塞业务读写操作
该方式下可回收的碎片化空间效果可能不如以上三种索引重建的方式
基本语法:

DBCC INDEXDEFRAG (${db_name}, '${schema_name}.${table_name}', ${index_name});

3 空间回收

需要注意的是,在SQL Server数据库,我们对表空间数据进行碎片化处理、或者truncate清空无效历史数据,这些释放出来的空间只是空出来,当有新数据写入时,优先使用这些空出来的数据页,而不是再向OS申请新的数据空间扩展。所以这部分并不会直接释放给OS,如果我们想要达到降低整个OS的磁盘空间使用率的话,还需要对数据库的数据文件进行收缩。

检查数据文件空间使用率

-- 检查数据库文件空间使用率SELECT a.name [文件名称] ,cast(a.[size]*1.0/128 as decimal(12,1)) AS [文件设置大小(MB)] ,    CAST( fileproperty(s.name,'SpaceUsed')/(8*16.0) AS DECIMAL(12,1)) AS [文件所占空间(MB)] ,    CAST( (fileproperty(s.name,'SpaceUsed')/(8*16.0))/(s.size/(8*16.0))*100.0 AS DECIMAL(12,1)) AS [所占空间率%] ,    CASE WHEN A.growth =0 THEN '文件大小固定,不会增长' ELSE '文件将自动增长' end [增长模式] ,CASE WHEN A.growth > 0 AND is_percent_growth = 0     THEN '增量为固定大小' WHEN A.growth > 0 AND is_percent_growth = 1 THEN '增量将用整数百分比表示' ELSE '文件大小固定,不会增长' END AS [增量模式] ,    CASE WHEN A.growth > 0 AND is_percent_growth = 0 THEN cast(cast(a.growth*1.0/128as decimal(12,0)) AS VARCHAR)+'MB'     WHEN A.growth > 0 AND is_percent_growth = 1 THEN cast(cast(a.growth AS decimal(12,0)) AS VARCHAR)+'%' ELSE '文件大小固定,不会增长' end AS [增长值(%或MB)] ,    a.physical_name AS [文件所在目录] ,a.type_desc AS [文件类型] FROM sys.database_files a INNER JOIN sys.sysfiles AS s  ON a.[file_id]=s.fileid LEFT JOIN sys.dm_db_file_space_usage b ON a.[file_id]=b.[file_id] ORDER BY a.[type]

收缩数据文件

USE [${db_name}]GODBCC SHRINKDATABASE(N'${db_name}' )GO

关于“SQL Server表空间碎片化回收怎么实现”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“SQL Server表空间碎片化回收怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯