SQL Server 2008 释放堆表空间
来源:互联网 发布:网络视频测试地址 编辑:程序博客网 时间:2024/06/05 14:11
前些天我遇到一个问题,一个200Gb的库,其中一个表大约2000W行数据,我删除了其中约600W行数据。我想把删除后未使用的空间腾出来。
按照以往的经验,重建这个表上的聚集索引就可以了。可是这次没有起效。原来这个表上只有一个非聚集主键索引。如何释放这个堆表未使用的空间
首先来模拟出我遇到的情况:
USE master
GO
CREATE DATABASE TEST;
GO
USE TEST
GO
--每一行占一个PAGE.
CREATE TABLE tb_Test
(
id INT NOT NULL ,
val CHAR(8000)
);
ALTER TABLE dbo.tb_Test
ADD CONSTRAINT PK_tbTest_id PRIMARY KEY NONCLUSTERED (id);
GO
INSERT INTO dbo.tb_Test
( id, val )
VALUES ( 1, REPLICATE('A',10)),( 2, REPLICATE('B',10)),
( 3, REPLICATE('C',10)),( 4, REPLICATE('D',10)),
( 5, REPLICATE('E',10)),( 6, REPLICATE('F',10)),
( 7, REPLICATE('E',10)),( 8, REPLICATE('F',10)),
( 9, REPLICATE('E',10)),( 10, REPLICATE('F',10));
GO
DBCC SHOWCONTIG('tb_Test');
GO
(10 行受影响)
DBCC SHOWCONTIG 正在扫描 'tb_Test' 表...
表: 'tb_Test' (85575343);索引 ID: 0,数据库 ID: 12
已执行 TABLE 级别的扫描。
- 扫描页数................................: 10
- 扫描区数..............................: 5
- 区切换次数..............................: 4
- 每个区的平均页数........................: 2.0
- 扫描密度 [最佳计数:实际计数].......: 40.00% [2:5]
- 区扫描碎片 ..................: 80.00%
- 每页的平均可用字节数.....................: 83.0
- 平均页密度(满).....................: 98.97%
每行占用一个页所以共有10页,接下来我删除其它5行。
DELETE FROM dbo.tb_Test
WHERE id<6;
GO
DBCC SHOWCONTIG('tb_Test');
GO
(5 行受影响)
DBCC SHOWCONTIG 正在扫描 'tb_Test' 表...
表: 'tb_Test' (85575343);索引 ID: 0,数据库 ID: 12
已执行 TABLE 级别的扫描。
- 扫描页数................................: 10
- 扫描区数..............................: 5
- 区切换次数..............................: 4
- 每个区的平均页数........................: 2.0
- 扫描密度 [最佳计数:实际计数].......: 40.00% [2:5]
- 区扫描碎片 ..................: 80.00%
- 每页的平均可用字节数.....................: 4088.5
- 平均页密度(满).....................: 49.49%
仍然占用10页,怎么释放出这“空余”的5页?
尝试1:把非聚集主键索引改成聚集,再把它改回来。因为聚集索引的叶级页是数据本身,所以创建或者重建都会重新组织数据页。
ALTER TABLE [dbo].[tb_Test] DROP CONSTRAINT [PK_tbTest_id];
ALTER TABLE dbo.tb_Test
ADD CONSTRAINT PK_tbTest_id PRIMARY KEY CLUSTERED (id);
ALTER TABLE [dbo].[tb_Test] DROP CONSTRAINT [PK_tbTest_id];
ALTER TABLE dbo.tb_Test
ADD CONSTRAINT PK_tbTest_id PRIMARY KEY NONCLUSTERED (id);
GO
DBCC SHOWCONTIG('tb_Test');
GO
DBCC SHOWCONTIG 正在扫描 'tb_Test' 表...
表: 'tb_Test' (85575343);索引 ID: 0,数据库 ID: 12
已执行 TABLE 级别的扫描。
- 扫描页数................................: 5
- 扫描区数..............................: 3
- 区切换次数..............................: 2
- 每个区的平均页数........................: 1.7
- 扫描密度 [最佳计数:实际计数].......: 33.33% [1:3]
- 区扫描碎片 ..................: 66.67%
- 每页的平均可用字节数.....................: 83.0
- 平均页密度(满).....................: 98.97%
这种做法有效。
尝试2:收缩数据文件。无论是SHRINKDATABASE或是SHRINKFILE原理都是一样的。执行下面查询时,要回滚“尝试1”的操作。
DBCC SHRINKFILE(TEST);
DBCC SHOWCONTIG('tb_Test');
GO
DBCC SHOWCONTIG 正在扫描 'tb_Test' 表...
表: 'tb_Test' (149575571);索引 ID: 0,数据库 ID: 12
已执行 TABLE 级别的扫描。
- 扫描页数................................: 5
- 扫描区数..............................: 3
- 区切换次数..............................: 2
- 每个区的平均页数........................: 1.7
- 扫描密度 [最佳计数:实际计数].......: 33.33% [1:3]
- 区扫描碎片 ..................: 66.67%
- 每页的平均可用字节数.....................: 83.0
- 平均页密度(满).....................: 98.97%
这种做法也有效。但是在生产环境中,特别是较大的库执行,影响特别大,容易产生大量碎片,一般不会用到。做为紧急应对的一种方法吧。
总结:
1. 郁闷。我的生产环境中,在做了“尝试1”并未起到效果,最后闲时维护使用“尝试2”才释放出来的。这点才是我做实验和写此文的初衷。
2. 不管什么表,最好还是建立一个聚集索。利于管理使用空间,不然像5行数据占据10行的空间,这种事情会经常发生。
- SQL Server 2008 释放堆表空间
- sql server tempdb 空间释放
- sql server 清空表后 释放空间语句
- sql server 2008删除表后内存没有释放
- Sql Server 内存释放
- SQL Server 2008空间数据类型
- SQL Server 表空间问题
- SQL Server 表空间问题
- sql server查看表空间
- 用指针释放堆中空间
- 堆空间的开辟与释放
- 字符串堆空间释放报错bug
- 释放UNDO表空间
- SQL server 强制释放内存
- sql server中如何创建,使用,释放临时表
- sql server 2008 空间数据类型的插入
- SQL Server查看表空间占用情况
- SQL Server 查看表占用空间
- Chapter 1 Arrays and Strings - 1.8
- Core-Plot的.a文件不能支持armv6解决方法
- MFC文件操作
- 如何在Oracle中复制表结构和表数据 【转载】
- Android 蓝牙 java.io.IOException: Connection refused 异常处理笔记
- SQL Server 2008 释放堆表空间
- 指尖上的Android之实战篇(四)
- 如何进行Android单元测试
- 安装 Discuz!X2.5 出现 you don't have permission to access /install on this server
- VC++项目开发笔记——打开或保存指定类型的文件CFileDialog类
- Markup类 xml文件操作
- 超级终端串口发送命令,uboot接收不到
- 使用纯代码编写了底部是tab一个视图有nav的例子
- Linux下PATH环境变量的修改