Applies to: SQL Server 2016 (13.x) and later
Azure SQL Database
Azure SQL Managed Instance
提供有关当前数据库中所有列存储索引的当前行组级信息。
This DMV extends the catalog view sys.column_store_row_groups.
Column name | Data type | Description |
---|---|---|
object_id |
int | 基础表的 ID。 |
index_id |
int | 表上的 object_id 此列存储索引的 ID。 |
partition_number |
int | 保存 row_group_id 的表分区的 ID。 可以使用partition_number将此 DMV 加入 sys.partitions |
row_group_id |
int | 此行组的 ID。 对于已分区表,值在分区中是唯一的。-1 用于内存中尾部。 |
delta_store_hobt_id |
bigint | 增量存储区中行组的hobt_id。NULL 如果行组不在增量存储中,NULL 用于内存中表的尾部。 |
state |
tinyint | 关联的 state_description ID 号。0 = INVISIBLE 1 = OPEN 2 = CLOSED 3 = COMPRESSED 4 = TOMBSTONE COMPRESSED 是应用于内存中表的唯一状态。 |
state_desc |
nvarchar(60) | 行组状态的说明:0
-
INVISIBLE - 正在生成的行组。 For example:列存储中的行组正在 INVISIBLE 压缩数据。 压缩完成后,元数据开关会将列存储行组的状态更改为INVISIBLE COMPRESSED “增量存储行组”的状态。CLOSED TOMBSTONE 1
-
OPEN - 接受新行的增量存储行组。 打开的行组仍采用行存储格式,并且尚未压缩为列存储格式。2
-
CLOSED - 增量存储区中包含最大行数的行组,并等待元组移动器进程将其压缩到列存储中。3
-
COMPRESSED - 使用列存储压缩压缩并存储在列存储中的行组。4
-
TOMBSTONE - 以前在增量存储中且不再使用的行组。 |
total_rows |
bigint | 以物理方式存储在行组中的行数。 对于压缩行组。 包括标记为已删除的行。 |
deleted_rows |
bigint | 以物理方式存储在压缩行组中且标记为要删除的行数。0 用于增量存储中的行组。对于非聚集列存储索引,此值不包括存储在删除缓冲区中的已删除行。 For more information, and to find the number of deleted rows in the delete buffer, see sys.internal_partitions. |
size_in_bytes |
bigint | 此行组中所有页面的组合大小(以字节为单位)。 此大小不包括存储元数据或共享字典所需的大小。 |
trim_reason |
tinyint | 触发 COMPRESSED 行组小于最大行数的原因。0 - UNKNOWN_UPGRADED_FROM_PREVIOUS_VERSION 1 - NO_TRIM 2 - BULKLOAD 3 - REORG 4 - DICTIONARY_SIZE 5 - MEMORY_LIMITATION 6 - RESIDUAL_ROW_GROUP 7 - STATS_MISMATCH 8 - SPILLOVER 9 - AUTO_MERGE |
trim_reason_desc |
nvarchar(60) |
trim_reason 说明。0
-
UNKNOWN_UPGRADED_FROM_PREVIOUS_VERSION :从以前版本的 SQL Server 升级时发生。1
-
NO_TRIM :未剪裁行组。 行组已压缩,最多包含 1,048,576 行。 如果在关闭增量行组后删除了行的子集,则行数可能更少2
-
BULKLOAD :大容量加载批大小限制行数。3
-
REORG :作为命令的 REORG 一部分强制压缩。4
-
DICTIONARY_SIZE :字典大小太大,无法将所有行压缩在一起。5
-
MEMORY_LIMITATION :没有足够的可用内存来压缩所有行。6
-
RESIDUAL_ROW_GROUP :在索引生成作期间,作为最后一行组的一部分关闭,其中行 < 数为 100 万行。Note: A partition build with multiple cores can result in more than one trim of this type. 7
-
STATS_MISMATCH :仅适用于内存中表上的列存储。 如果统计信息未正确指示 >= 结尾中的 100 万个限定行,但我们发现更少,则压缩行组将有 < 100 万行8
-
SPILLOVER :仅适用于内存中表上的列存储。 如果 tail 有 > 100 万个限定行,则如果计数介于 100,000 到 100 万之间,则会压缩最后一批剩余的行9
-
AUTO_MERGE :在后台运行的元组 Mover 合并作将一个或多个行组合并到此行组中。 |
transition_to_compressed_state |
tinyint | 显示此行组是如何从增量存储移动到列存储中的压缩状态的。1 - NOT_APPLICABLE 2 - INDEX_BUILD 3 - TUPLE_MOVER 4 - REORG_NORMAL 5 - REORG_FORCED 6 - BULKLOAD 7 - MERGE |
transition_to_compressed_state_desc |
nvarchar(60) |
1
-
NOT_APPLICABLE -作不适用于增量存储。 或者,在升级到 SQL Server 2016(13.x)之前压缩行组,在这种情况下不会保留历史记录。2
-
INDEX_BUILD - 索引创建或索引重新生成压缩行组。3
-
TUPLE_MOVER - 在后台运行的元组移动器压缩了行组。 元组移动器在行组更改状态OPEN 后发生。CLOSED 4
-
REORG_NORMAL - 重组作, ALTER INDEX ... REORG 将 CLOSED 行组从增量存储移动到列存储。 这发生在元组移动器有时间移动行组之前。5
-
REORG_FORCED - 此行组在增量存储中处于打开状态,并被迫进入列存储,然后才具有完整行数。6
-
BULKLOAD - 大容量加载作直接压缩行组,而无需使用增量存储。7
-
MERGE - 合并作将一个或多个行组合并到此行组中,然后执行列存储压缩。 |
has_vertipaq_optimization |
bit | VertiPaq 优化通过重新排列行组中行的顺序来提高列存储压缩,以实现更高的压缩。 在大多数情况下,会自动进行此优化。 在以下两种情况下,未使用 VertiPaq 优化: a. 当增量行组移动到列存储中并且列存储索引上存在一个或多个非聚集索引时 -在这种情况下,将跳过 VertiPaq 优化以最大程度地减少对映射索引的更改; b. 用于内存优化表上的列存储索引。 0 = 否1 = 是 |
generation |
bigint | 与此行组关联的行组生成。 |
created_time |
datetime2 | 创建此行组时的时钟时间。NULL - 对于内存中表上的列存储索引。 |
closed_time |
datetime2 | 此行组关闭时的时钟时间。NULL - 对于内存中表上的列存储索引。 |
Results
返回当前数据库中每个行组的一行。
Permissions
CONTROL
需要对表具有权限和VIEW DATABASE STATE
数据库权限。
SQL Server 2022 及更高版本的权限
需要对数据库拥有 VIEW DATABASE PERFORMANCE STATE
权限。
Examples
A. 计算碎片以决定何时重新组织或重新生成列存储索引
对于列存储索引,已删除行的百分比是行组中碎片的良好度量值。 当碎片为 20% 或更多时,请删除已删除的行。 有关更多示例,请参阅 优化索引维护以提高查询性能并减少资源消耗。
此示例与其他系统表联接 sys.dm_db_column_store_row_group_physical_stats
,然后将列计算 Fragmentation
为当前数据库中每一行组的效率的估计值。 若要查找有关单个表的信息,请删除子句前面的 WHERE
注释连字符并提供表名。
SELECT i.object_id,
object_name(i.object_id) AS TableName,
i.name AS IndexName,
i.index_id,
i.type_desc,
CSRowGroups.*,
100 * (ISNULL(deleted_rows, 0)) / NULLIF (total_rows, 0) AS 'Fragmentation'
FROM sys.indexes AS i
INNER JOIN sys.dm_db_column_store_row_group_physical_stats AS CSRowGroups
ON i.object_id = CSRowGroups.object_id
AND i.index_id = CSRowGroups.index_id
-- WHERE object_name(i.object_id) = 'table_name'
ORDER BY object_name(i.object_id), i.name, row_group_id;