Jor*_*anT 3 index sql-server blob sql-server-2016 index-maintenance
我有第三部分应用程序,其中有一个 450GB 的表,其中在 TEXT 列中包含文件附件(是的,我知道)。通过文档保留角度,我已使用便携式驱动器将大约 35% 的旧附件导出到磁盘。TEXT 列现在有一条注释,表明附件已存档(有利于应用程序的 UI) - 从多个 MB/GB 减少到不到 1KB。
我知道反对缩小数据库的论点。我从这个论坛收集的选项包括(1)复制表、删除原始表、重命名副本、(2)使用 xp_cmdshell 'bcp...' 导出表、截断表、使用 BULK INSERT 从 'c: 导入数据。 ..' 和 ...; (3) 运行 ALTER INDEX ALL ON dbo.Table REORGANIZE WITH (LOB_COMPACTION = ON)
我最关心的是 SQL Server 将用于任何选项的资源(磁盘空间、CPU、内存...),特别是考虑到表的大小。至于时间,如果需要,我可以阻止周末时间,但是日志文件、临时数据库文件等呢?在开始使用这些选项中的任何一个之前,我应该设置/更改哪些设置?
该服务器具有 160GB 内存,其中 128GB 用于 SQL Server (2016),2 个节点,配有 20 个处理器,每个节点在 MS Windows Server 2012 R2 标准上额定频率为 2.2 GHz。
您的选择的缺点似乎是:
bcp
并重新导入它很混乱,并且您仍然需要所有这些空间,尽管不在 SQL Server 本身中。如果表很小,无论如何都比选项 1 没有任何好处。REORGANIZE WITH (LOB_COMPACTION = ON)
可能会非常慢,并且可能还需要额外的空间。由于大量的页和行移动,它还会使事务日志膨胀。比您提供的任何选项更好的选择是桌子开关。
与删除/重命名的想法类似,您创建一个与原始表完全相同的新临时表。将要保留的数据插入新表中。然后截断旧的并切换新的。切换是一种快速的元数据操作,只需要交换表头。
假设您有一个现有的表
CREATE TABLE MainTable (
id int PRIMARY KEY IDENTITY,
document text
);
Run Code Online (Sandbox Code Playgroud)
您需要准确复制架构,这包括主/唯一/外部/检查约束和索引。IDENTITY
不需要在那里,如果将其省略,可能会更容易。您可以通过右键单击 SSMS 中的表并选择 来快速创建此架构的副本Script Table As -> CREATE
。
CREATE TABLE CopyTable (
id int PRIMARY KEY,
document text
);
Run Code Online (Sandbox Code Playgroud)
然后你就可以将所有数据复制到
BEGIN TRAN;
INSERT CopyTable WITH (TABLOCKX)
(id, document)
SELECT id, document
FROM MainTable WITH (TABLOCK);
Run Code Online (Sandbox Code Playgroud)
并截断旧表并切换
TRUNCATE TABLE MainTable;
ALTER TABLE CopyTable
SWITCH TO MainTable;
-- if you have an IDENTITY column then:
DBCC CHECKIDENT ('MainTable');
COMMIT;
Run Code Online (Sandbox Code Playgroud)
最后删除复制表,它现在是空的:
DROP TABLE CopyTable;
Run Code Online (Sandbox Code Playgroud)
您可以移动或删除BEGIN TRAN
和 ,COMMIT
具体取决于同时运行的其他内容。
我建议您将列数据类型从text
(已弃用)更改为varchar(max)
. 据我所知,它们隐式地相互转换,因此这根本不会影响应用程序。varchar(max)
优点是可以在行内存储 <8kb 值,而不是在 LOB 页上。
我建议您在复制表格之前执行此操作。
归档时间: |
|
查看次数: |
245 次 |
最近记录: |