LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL Server 数据库空间优化

admin
2026年3月12日 21:37 本文热度 63

第一阶段:现状查询

1. 查询数据库物理与实际使用大小

通过此脚本可以明确磁盘占用、纯数据大小以及浪费的空闲空间

SELECT     name AS FileName,    size*8/1024.0 AS TotalSize_MB,  -- 磁盘占用    CAST(FILEPROPERTY(name, 'SpaceUsed'AS INT)*8/1024.0 AS UsedSize_MB, -- 实际数据    (size - CAST(FILEPROPERTY(name, 'SpaceUsed'AS INT))*8/1024.0 AS FreeSize_MB -- 可回收空间FROM sys.database_files;

2. 查询索引碎片情况

碎片率超过 30% 会严重影响查询性能

SELECT     dbschemas.[name] as 'Schema'    dbtables.[name] as 'Table'    dbindexes.[name] as 'Index',    indexstats.avg_fragmentation_in_percentFROM sys.dm_db_index_physical_stats (DB_ID(), NULLNULLNULL'LIMITED'AS indexstatsINNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]    AND indexstats.index_id = dbindexes.index_idWHERE indexstats.avg_fragmentation_in_percent > 30ORDER BY indexstats.avg_fragmentation_in_percent DESC;


第二阶段:空间清理

3. 清除无用表

在收缩数据库前,优先删除以 tmptempbak 开头的废弃表,这是最真实的空间释放。

-- 生成删除脚本(请务必在执行前核对结果,确保表已不再需要)SELECT 'DROP TABLE [' + s.name + '].[' + t.name + '];'FROM sys.tables tJOIN sys.schemas s ON t.schema_id = s.schema_idWHERE t.name LIKE 'tmp%'    OR t.name LIKE 'temp%'    OR t.name LIKE 'bak%';
4. 缩小数据库(释放物理磁盘空间)

建议不要使用全自动收缩,而是手动执行并“留有余地”。因后续在重建索引时,SQL Server 需要额外的空间来存放临时数据,分安全截断和按需截断。

  • 安全截断(不搬动数据,不产生碎片,仅释放末尾空间)

    • 速度极快: 因为不涉及数据搬运。

    • 零副作用: 绝对不会产生索引碎片。

    • 它的行为: 它只看数据库文件的“末尾”。如果文件末尾有一块连续的空白空间,它会直接把这部分还给操作系统。它不会移动任何文件内部的数据页。

    • 优点:

    • 缺点: 效果有限。如果文件的末尾哪怕只存了 1KB 的数据,那么这 1KB 之前的所有空白空间都无法释放

    • 适用场景: 数据库刚删除了大量末尾数据,或者作为日常维护的第一步。

DBCC SHRINKFILE (1, TRUNCATEONLY);
按需收缩(保留 10% 缓冲空间,重组并释放空间):

  • 它的行为: 它会进行“数据搬运”。它会把文件末尾的数据页强行移动到文件前面的空白处,把空间“挤”出来,直到文件缩小到只剩下你指定的比例(在此处是保留 10% 的空闲缓冲区)。

  • 优点:

    • 效果显著: 无论空白空间在文件的什么位置,都能被挤出来并释放。

  • 缺点:

    • 产生严重碎片: 搬运数据页会打乱索引的物理顺序。你之前查到的 99% 碎片大多就是由这类操作引起的。

    • 消耗资源: 搬运数据需要大量的磁盘 I/O 和 CPU 资源。

  • 适用场景: 磁盘空间极度紧张,必须腾出空间时使用。

DBCC SHRINKDATABASE (N'dbname'10);


第三阶段:性能修复

修复索引碎片(Rebuild)

收缩操作会导致索引碎片飙升。必须在收缩后(建议业务低峰期)进行重建。

手动重建单个索引

ALTER INDEX [索引名] ON [表名] REBUILD;
建议使用批量生成重建脚本(针对碎片率 >30% 的所有索引):

  • 针对性强:它只针对 avg_fragmentation_in_percent > 30 的索引,不会浪费资源去重建那些本来就很整齐的索引。

  • 自动化:你不需要手动去一个个输入表名和索引名,它通过系统视图 sys.indexes 和 sys.tables 自动帮你完成了拼接工作。

  • 安全可控:因为它只是生成语句,你可以先审查一遍,剔除掉那些你不想处理的表(比如某些 tmp 表),然后再手动执行。

SELECT 'ALTER INDEX [' + i.name + '] ON [' + s.name + '].[' + t.name + '] REBUILD;'FROM sys.dm_db_index_physical_stats(DB_ID(), NULLNULLNULL'LIMITED'AS avg_fragJOIN sys.indexes AS i ON avg_frag.object_id = i.object_id AND avg_frag.index_id = i.index_idJOIN sys.tables AS t ON i.object_id = t.object_idJOIN sys.schemas AS s ON t.schema_id = s.schema_idWHERE avg_frag.avg_fragmentation_in_percent > 30 AND i.name IS NOT NULL;



核心避坑总结

  1. 先清理再收缩:先 DROP 无用表,再执行 SHRINK

  2. 收缩必有碎片SHRINK 操作会像打乱拼图一样破坏索引物理顺序,导致查询变慢。

  3. 重建才是终点:只有完成了 REBUILD,数据库才算真正完成了优化。

  4. 低峰期操作:重建索引会锁表并消耗高 I/O,请务必安排在深夜或凌晨执行。


阅读原文:原文链接


该文章在 2026/3/13 11:41:20 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved