SQL Server 2019聚集列存储索引页填充率及碎片率均为0问题咨询
聚集列存储索引页填充率/碎片率为0的常见原因
聚集列存储索引(CCI)的存储结构与传统行存储索引完全不同,核心存储单元是*行组(Row Group)*而非行存储的8KB数据页,SSMS索引属性页显示的「页填充率」「总碎片率」默认基于行存储页的统计逻辑,对列存储索引的兼容性存在局限,出现0值的具体原因可分为以下几类:
- 统计逻辑适配问题:如果你使用的SSMS版本低于18.x,或调用
sys.dm_db_index_physical_stats时使用了LIMITED扫描模式,该模式不会解析列存储行组的内部存储结构,对于未完全压缩为列式存储的增量行组(Delta Store),会直接返回0%的页填充率和碎片率。另一张可正常显示数值的表,其行组已全部被压缩为封闭的COLUMNSTORE类型行组,可被统计逻辑正常识别。 - 行组未触发自动压缩:如果该表的CCI创建后,数据均通过小批量插入、单条插入的方式写入,所有行都保留在OPEN状态的增量行组中,没有触发SQL Server后台Tuple Mover的自动压缩逻辑。你默认执行的索引重组操作只会压缩已经封闭的增量行组,对OPEN状态的行组无效,因此操作后统计值无变化。
- 元数据统计未更新:索引创建或数据写入后,统计信息没有自动刷新,导致系统视图返回旧的无效值。
- SQL Server 2019已知问题:如果你的实例安装的累积更新(CU)低于CU15,存在列存储索引元数据统计错误的已知bug,会出现页填充率、碎片率统计为0的异常。
验证与修复方法
你可以执行以下语句查询该表的行组状态,确认是否为增量行组未压缩的问题:
SELECT row_group_id, state_desc, total_rows, deleted_rows, size_in_bytes FROM sys.dm_db_column_store_row_group_physical_stats WHERE object_id = OBJECT_ID('替换为你的表名')
如果查询结果中大部分行组的state_desc为OPEN或者CLOSED,说明行组未被压缩,执行以下语句强制压缩所有行组即可:
ALTER INDEX [替换为你的聚集列存储索引名] ON [替换为你的表名] REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON)
如果是统计信息未更新的问题,执行以下语句刷新统计即可:
UPDATE STATISTICS [替换为你的表名] WITH FULLSCAN
如果是版本bug问题,升级到SQL Server 2019最新累积更新即可解决。
内容的提问来源于stack exchange,提问作者bookofproofs
相关产品推荐
相关产品推荐

