Der*_*nch 11 sql-server sql-server-2012
我在 SQL Server 2012 Express 中有一个表,有很多未使用的空间。
我需要释放数据库中的空间。
| 姓名 | 行 | 保留 | 数据 | INDEX_SIZE | 未使用 | |-------------|--------|--------------|----------- ---|------------|--------------| | 我的表名 | 158890 | 8928296 KB | 5760944 KB | 2248 KB | 3165104 KB |
如何让 SQL 释放 3165104KB?
我已经试过了:
Alter table MyTableName Rebuild
DBCC CLEANTABLE (MyDbName,"MyTableName ", 0)
ALTER INDEX ALL ON MyTableName REORGANIZE ;
ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF)
Run Code Online (Sandbox Code Playgroud)
这是表:
CREATE TABLE [dbo].[MyTableName](
[ImageID] [int] IDENTITY(1,1) NOT NULL,
[DateScan] [datetime] NULL,
[ScanImage] [image] NULL,
CONSTRAINT [PK_Image] PRIMARY KEY CLUSTERED
(
[ImageID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
我们所做的唯一一件事就是ScanImage用一个更小的图像替换每一行(这是有多少未使用的空间)。
Mar*_*ith 10
我们所做的唯一一件事是
ScanImage用一个更小的图像替换每一行(这是有多少未使用的空间)
通过进行一些实验,最节省空间的方法是删除分配单元并重新填充它(如果您有一个维护窗口来执行此操作)。
使用问题中的表结构为我实现最佳空间减少的示例代码是:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET XACT_ABORT ON;
BEGIN TRAN
SELECT [ImageID],
[ScanImage]
INTO #Temp
FROM [dbo].[MyTableName]
ALTER TABLE [dbo].[MyTableName]
DROP COLUMN [ScanImage]
/*Allocation unit not removed until after this*/
ALTER INDEX PK_Image ON MyTableName REBUILD
ALTER TABLE [dbo].[MyTableName]
ADD [ScanImage] IMAGE NULL
UPDATE [dbo].[MyTableName]
SET [ScanImage] = T.[ScanImage]
FROM [dbo].[MyTableName] M
JOIN #Temp T
ON M.ImageID = T.[ImageID]
DROP TABLE #Temp
COMMIT
Run Code Online (Sandbox Code Playgroud)
一切都在事务中,因此如果机器崩溃,它将被回滚。可能可以做一些错误处理或至少SET XACT_ABORT ON。我曾经SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;防止在复制期间或之后发生任何并发修改并丢失。
减少image所有行的大小后保留的LOB页数如下:
+------------------------------------------------- -+---------------------+-------------------------+ | 活动 | lob_used_page_count | lob_reserved_page_count | +------------------------------------------------- -+---------------------+-------------------------+ | 插入 10,000 行,每行 100,000 字节数据 | 135005 | 135017 | | 将所有行更新为 10,000 字节图像数据 | 31251 | 135012 | | 重组 | 23687 | 25629 | | 删除并重新添加图像数据 | 13485 | 13489 | +------------------------------------------------- -+---------------------+-------------------------+
尝试
ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF)
这将重新创建聚集索引,因此您将需要在数据库中留出额外空间来完成操作。如果由于磁盘已满而没有任何额外空间,则可以向数据库(在不同磁盘上)添加一个新数据文件并将表移动到该数据库中。
也可能使用小于 100% 的 FILLFACTOR 定义聚集索引。将填充因子设置为例如 66%,将使每个数据页的 1/3 留空以备将来使用。如果这是问题,您可以使用修改填充因子ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF, FILLFACTOR=100)
如果您最近从表中删除了可变长度字段,您也可以尝试 DBCC CLEANTABLE( Databasename, "MyTableName")
在线书籍 (BOL) 在http://technet.microsoft.com/en-us/library/ms188388%28v=sql.100%29.aspx上有一篇关于重建索引的精彩文章