Sae*_*ati 8 sql-server shrink dbcc database-size
这个问题被问了几十次,令我惊讶的是,这样一个简单的要求变得如此困难。然而我无法解决这个问题。
我使用 SQL Server 2014 Express 版,数据库大小限制为 10GB(不是文件组大小,数据库大小)。
我抓取了新闻,并将 HTML 插入到表格中。表的架构是:
Id bigint identity(1, 1) primary key,
Url varchar(250) not null,
OriginalHtml nvarchar(max),
...
Run Code Online (Sandbox Code Playgroud)
数据库容量不足,我收到了 insufficient disk space
当然缩小数据库和文件组没有帮助。DBCC SHRINKDATABASE
没有帮助。所以我写了一个简单的应用程序来读取每条记录,去掉一些不需要的部分,OriginalHtml
比如 head section 和 aside 和 footer 以只保留主体,现在我在获取顶级表的磁盘使用情况报告时看到这个图像:
据我了解这张图片,未使用的空间现在占总大小的 50%。也就是说,现在我有 5GB 未使用的空间。但我无法收回它。重建索引没有帮助。该truncateonly
选项无济于事,因为据我所知,没有记录被删除,只有每条记录的大小减少。
我被困在这一点上。请帮忙,我该怎么办?
聚集索引在列上Id
。
这是结果 EXECUTE sys.sp_spaceused @objname = N'dbo.Articles', @updateusage = 'true';
name rows reserved data index_size unused
----------- -------- ------------ ----------- ------------ -----------
Articles 112258 8079784 KB 5199840 KB 13360 KB 2866584 KB
Run Code Online (Sandbox Code Playgroud)
Pau*_*ite 10
在所有条件相同的情况下,压缩大对象 (LOB) 列应该足够了OriginalHTML
。您没有在问题中指定聚集索引名称,因此:
ALTER INDEX ALL
ON dbo.Articles
REORGANIZE
WITH (LOB_COMPACTION = ON);
Run Code Online (Sandbox Code Playgroud)
如果您有聚集索引名称(不仅仅是聚集列),请ALL
用该名称替换以上内容。
该LOB_COMPACTION
选项默认为ON
,但明确表示没有坏处。您可能需要REORGANIZE
重复运行以完成回收所有未使用的空间。
不幸的是,LOB 数据的组织方式和 LOB 压缩的实现方式意味着无论您运行多少次,此方法可能并不总是能够回收所有未使用的空间。它也可能非常缓慢。
您也可以尝试相关问答中释放未使用空间 SQL Server 表中的方法
如果出于某种原因,上述方法对您不起作用,请将数据导出到文件,截断表,然后重新加载它。有几种方法可以实现这一点,例如bcp 实用程序。
下面创建一个包含 10,000 行宽的表:
CREATE TABLE dbo.Test
(
c1 bigint IDENTITY NOT NULL,
c2 nvarchar(max) NOT NULL,
CONSTRAINT PK_dbo_Test
PRIMARY KEY CLUSTERED (c1)
);
-- Load 10,000 wide rows
INSERT dbo.Test WITH (TABLOCKX)
(c2)
SELECT TOP (10000)
REPLICATE(CONVERT(nvarchar(max), 'X'), 50000)
FROM master.sys.columns AS C1
CROSS JOIN master.sys.columns AS C2;
Run Code Online (Sandbox Code Playgroud)
我们可以使用sys.dm_db_index_physical_stats
DMV查看空间使用情况:
SELECT
DDIPS.index_id,
DDIPS.partition_number,
DDIPS.index_type_desc,
DDIPS.index_depth,
DDIPS.index_level,
DDIPS.page_count,
DDIPS.avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats
(
DB_ID(),
OBJECT_ID(N'dbo.Test', N'U'),
1,
NULL,
'DETAILED'
) AS DDIPS
WHERE
DDIPS.alloc_unit_type_desc = N'LOB_DATA';
Run Code Online (Sandbox Code Playgroud)
我们现在将 LOB 内容更新为较小的大小(但仍需要行外存储):
-- Change LOB data to a smaller value (that will not move in-row)
UPDATE dbo.Test WITH (TABLOCKX)
SET c2 = REPLICATE(CONVERT(nvarchar(max), 'Y'), 5000);
Run Code Online (Sandbox Code Playgroud)
请注意,一些空间已被回收,但剩余的页面比以前少了很多。
我们可以使用以下方法压缩 LOB 空间:
ALTER INDEX PK_dbo_Test ON dbo.Test
REORGANIZE
WITH (LOB_COMPACTION = ON);
Run Code Online (Sandbox Code Playgroud)
这会导致一些压缩和空间节省,但它并不完美。再次运行压缩可能会也可能不会改善这种情况。在我的测试中,无论我重新运行多少次,它都没有。
完全从 Management Studio 执行此操作的一种方法涉及使用xp_cmdshell
将表数据导出到文件。如果xp_cmdshell
当前未启用,则执行以下操作:
-- Enable xp_cmdshell if necessary
EXECUTE sys.sp_configure
@configname = 'show advanced options',
@configvalue = 1;
RECONFIGURE;
EXECUTE sys.sp_configure
@configname = 'xp_cmdshell',
@configvalue = 1;
RECONFIGURE;
Run Code Online (Sandbox Code Playgroud)
现在我们可以执行导出:
-- Export table
EXECUTE sys.xp_cmdshell
'bcp Sandpit.dbo.Test out c:\temp\Test.bcp -n -S .\SQL2017 -T';
Run Code Online (Sandbox Code Playgroud)
请注意,您需要更改路径和-S
服务器名称,并可能需要提供登录凭据。
我们如何截断表,并使用BULK INSERT
以下命令重新加载它:
-- Truncate
TRUNCATE TABLE dbo.Test;
-- Switch to BULK_LOGGED recovery model if currently set to FULL
-- Bulk load
BULK INSERT dbo.Test
FROM 'c:\temp\Test.bcp'
WITH
(
DATAFILETYPE = 'widenative',
ORDER (c1),
TABLOCK,
KEEPIDENTITY
);
Run Code Online (Sandbox Code Playgroud)
最后一步是重置身份种子:
-- Check and reseed identity
DBCC CHECKIDENT('dbo.Test', RESEED);
Run Code Online (Sandbox Code Playgroud)
此操作序列通常比 LOB 压缩更快,并且应始终产生最佳结果:
由于一个长期存在的错误,上面的效率并不高:BULK INSERT with IDENTITY 列创建了带有 SORT 的查询计划。那里列出的解决方法是有效的,但如果表非常大,我只会打扰它。
不要忘记删除用于保存导出数据的临时文件。
您当然可以自由使用最方便的批量导出/导入方法。不需要使用xp_cmdshell
或bcp
。
补充说明:
FILLFACTOR
仅适用于索引页。它不会影响行外 LOB 存储(不存储在索引页上)。
行和页压缩不适用于行外存储。
作为替代方法,您可以使用SQL Server 2016 中提供的COMPRESS
和DECOMPRESS
函数显式压缩和解压缩数据。
对于那些使用 SQL Server 2014(这里就是这种情况)或更早版本(直到 SQL Server 2005)获得COMPRESS
和DECOMPRESS
内置函数提供的相同压缩功能的人来说,一个选项是使用 SQLCLR。由Solomon Rutzky编写的免费版SQL#中提供了执行此操作的预构建函数。的Util_GZip和Util_GUnzip功能应相当于和,分别。而且,任何使用 SQL Server 2012 或更高版本的人都应确保使用 .NET Framework 4.5 或更高版本更新运行 SQL Server 的服务器,以便使用大大改进的压缩算法。COMPRESS
DECOMPRESS
归档时间: |
|
查看次数: |
10374 次 |
最近记录: |