SQLIndexManager列存储索引维护专题:从行组压缩到一键将堆转换为CCI
【免费下载链接】SQLIndexManagerFree GUI Tool for Index Maintenance on SQL Server and Azure项目地址: https://gitcode.com/gh_mirrors/sq/SQLIndexManager
SQL Index Manager(SQLIndexManager)是一款免费的 SQL Server 与 Azure 索引维护 GUI 工具,除了传统的行存索引维护,它还内置了完整的列存储索引维护能力:分析行组压缩状态、重建/压缩行组,以及一键将堆表转换为 CCI(聚集列存储索引)。本文带你从原理到操作,完整走通这条维护链路。
为什么列存储索引需要专门的维护
普通 B-Tree 索引的"碎片"是页与页之间的物理分散,而列存储索引的"碎片"完全是另一个概念。
列存储把数据按**行组(Row Group)**组织,每 100 万行(约 16MB)压成一个行组。数据写入时先以未压缩的 Delta 行组形式暂存,等攒够行数后才会被压缩成正式的 Columnstore 行组。维护的核心目标就是:
- 把残留的未压缩行组压缩掉,缩小体积
- 消除零散的未压缩行组,提高列扫描效率
- 对堆表(Heap),直接补建 CCI,把整张表变成列存储
在工具内部,列存储被识别为两种独立索引类型,定义在 Types/IndexType.cs 中:
CLUSTERED_COLUMNSTORE:聚集列存储(CCI)NONCLUSTERED_COLUMNSTORE:非聚集列存储(NCI)
行组压缩分析:工具如何量化"碎片"
传统索引用sys.dm_db_index_physical_stats算碎片率,而列存储没有这套数据,SQL Server 提供的是sys.fn_column_store_row_groups函数,其中state = 1表示未压缩(Delta)行组。
SQLIndexManager 的列存储扫描 SQL 在 Server/Query.cs 中定义,核心逻辑是:
Fragmentation = SUM(未压缩行组的 size_in_bytes) * 100.0 / SUM(所有行组的 size_in_bytes)也就是说:列存储的"碎片率"= 未压缩行组占用空间占总空间的比例。
扫描入口在 Server/QueryEngine.cs 的GetColumnstoreFragmentation方法中,同样支持按最小/最大索引大小和碎片阈值过滤,只关注真正需要处理的大表。
两种修复手段:REBUILD 还是 REORGANIZE
列存储索引的维护操作定义在 Types/IndexOp.cs 中,工具为列存储提供了两套思路:
方案一:REBUILD(彻底重建)
ALTER INDEX [CCL] ON [dbo].[FactTable] REBUILD WITH (DATA_COMPRESSION = COLUMNSTORE, MAXDOP = 4);- 可选
COLUMNSTORE或COLUMNSTORE_ARCHIVE压缩(对应 Types/DataCompression.cs) - Archive 级别压缩率更高、CPU 开销更大,适合冷数据
- 注意:列存储重建不支持在线(ONLINE = ON),工具在生成脚本时会自动去掉该选项
方案二:REORGANIZE + COMPRESS_ALL_ROW_GROUPS(轻量压缩)
ALTER INDEX [CCL] ON [dbo].[FactTable] REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);只压缩已有行组、不重写整个索引,执行快、资源消耗低,日常例行维护的首选。操作描述在 Types/IndexOp.cs 中对应REORGANIZE_COMPRESS_ALL_ROW_GROUPS。
维护完成后,工具还会执行 Server/Query.cs 中的AfterFixColumnstoreIndex查询,重新统计该分区的行组页数和剩余未压缩行组,在结果中直接展示"修完之后还剩多少没压缩",让效果一目了然。
一键将堆转换为 CCI:堆表维护的隐藏大招
这是本专题最亮眼的功能。堆表(Heap,即没有聚集索引的表)扫描到后,工具可以建议CREATE COLUMNSTORE INDEX操作,直接为整张表补建 CCI。
Server/Index.cs 中生成的脚本形如:
CREATE CLUSTERED COLUMNSTORE INDEX [CCL] ON [dbo].[FactSales] WITH (COMPRESSION_DELAY = 0, DATA_COMPRESSION = COLUMNSTORE);两个参数值得注意:
COMPRESSION_DELAY = 0:关闭默认的 60 秒压缩延迟,让 Delta 行组尽快被压缩DATA_COMPRESSION = COLUMNSTORE:明确指定列存储压缩级别
执行完成后,工具会把该行的类型同步更新为CLUSTERED_COLUMNSTORE(见 Server/QueryEngine.cs 中FixIndex方法的收尾逻辑),后续再维护时就按列存储流程走了。
对于分析型大表,"堆 → CCI"往往比反复 Reorganize 行存索引收益更大:体积更小、扫描更快、维护手段也升级成了上面那套行组压缩。
扫描配置与命令行自动化
列存储的扫描开关在 Settings/Options.cs 中单独控制:
ScanClusteredColumnstore:扫描聚集列存储ScanNonClusteredColumnstore:扫描非聚集列存储ScanHeap:扫描堆表(CCI 转换的前提)
并且只有当实例确实支持列存储时,这两类索引才会加入扫描范围(判断逻辑在 Server/QueryEngine.cs 的IsColumnstoreAvailable)。
在命令行模式下,Console/CmdWorker.cs 提供了ignorecolumnstore参数,可以只例行维护行存索引、跳过列存储扫描,方便你按天/按周拆分维护窗口。
小结
| 维护场景 | 推荐操作 | 关键参数 |
|---|---|---|
| 例行维护 CCI/NCI | REORGANIZE | COMPRESS_ALL_ROW_GROUPS = ON |
| 压缩率不够、数据冷 | REBUILD | DATA_COMPRESSION = COLUMNSTORE_ARCHIVE |
| 堆表大表、分析型负载 | CREATE COLUMNSTORE INDEX | COMPRESSION_DELAY = 0 |
| 修复后验证 | 自动回查行组 | 剩余未压缩行组占比 |
SQLIndexManager 把"分析行组 → 选择策略 → 生成 T-SQL → 一键执行 → 回查效果"整条链路都自动化了,列存储索引从此也能像普通索引一样进入你的例行维护计划。
【免费下载链接】SQLIndexManagerFree GUI Tool for Index Maintenance on SQL Server and Azure项目地址: https://gitcode.com/gh_mirrors/sq/SQLIndexManager
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考