sys.dm_db_column_store_row_group_physical_stats (Transact-SQL)

Applies to: SQL Server 2016 (13.x) and later Azure SQL Database Azure SQL Managed Instance

Provides current rowgroup-level information about all of the columnstore indexes in the current database.

This extends the catalog view sys.column_store_row_groups (Transact-SQL).

Column name Data type Description
object_id int ID of the underlying table.
index_id int ID of this columnstore index on object_id table.
partition_number int ID of the table partition that holds row_group_id. You can use partition_number to join this DMV to sys.partitions.
row_group_id int ID of this row group. For partitioned tables, value is unique within the partition.

-1 for an in-memory tail.
delta_store_hobt_id bigint The hobt_id for a row group in the delta store.

NULL if row group is not in the delta store.

NULL for tail of an in-memory table.
state tinyint ID number associated state_description.

0 = INVISIBLE

1 = OPEN

2 = CLOSED

3 = COMPRESSED

4 = TOMBSTONE

COMPRESSED is the only state that applies to in-memory tables.
state_desc nvarchar(60) Description of the row group state:

0 - INVISIBLE -A row group that is being built. For example:
A row group in the columnstore is INVISIBLE while the data is being compressed. When the compression is finished a metadata switch changes the state of the columnstore row group from INVISIBLE to COMPRESSED, and the state of the deltastore row group from CLOSED to TOMBSTONE.

1 - OPEN - A deltastore row group that is accepting new rows. An open row group is still in rowstore format and has not been compressed to columnstore format.

2 - CLOSED - A row group in the delta store that contains the maximum number of rows, and is waiting for the tuple mover process to compress it into the columnstore.

3 - COMPRESSED - A row group that is compressed with columnstore compression and stored in the columnstore.

4 - TOMBSTONE - A row group that was formerly in the deltastore and is no longer used.
total_rows bigint Number of rows physically stored in the row group. For compressed row groups. Includes the rows that are marked deleted.
deleted_rows bigint Number of rows physically stored in a compressed row group that are marked for deletion.

0 for row groups that are in the delta store.
size_in_bytes bigint Combined size, in bytes, of all the pages in this row group. This size does not include the size required to store metadata or shared dictionaries.
trim_reason tinyint Reason that triggered the COMPRESSED row group to have less than the maximum number of rows.

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) Description of trim_reason.

0 - UNKNOWN_UPGRADED_FROM_PREVIOUS_VERSION: Occurred when upgrading from the previous version of SQL Server.

1 - NO_TRIM: The row group was not trimmed. The row group was compressed with the maximum of 1,048,576 rows. The number of rows could be less if a subset of rows was deleted after delta rowgroup was closed

2 - BULKLOAD: The bulk-load batch size limited the number of rows.

3 - REORG: Forced compression as part of REORG command.

4 - DICTIONARY_SIZE: Dictionary size grew too large to compress all of the rows together.

5 - MEMORY_LIMITATION: Not enough available memory to compress all the rows together.

6 - RESIDUAL_ROW_GROUP: Closed as part of last row group with rows < 1 million during index build operation. Note: A partition build with multiple cores can result in more than one trim of this type.

7 - STATS_MISMATCH: Only for columnstore on in-memory table. If stats incorrectly indicated >= 1 million qualified rows in the tail but we found fewer, the compressed rowgroup will have < 1 million rows

8 - SPILLOVER: Only for columnstore on in-memory table. If tail has > 1 million qualified rows, the last batch remaining rows are compressed if the count is between 100k and 1 million

9 - AUTO_MERGE: A Tuple Mover merge operation running in the background consolidated one or more rowgroups into this rowgroup.
transition_to_compressed_state tinyint Shows how this rowgroup got moved from the deltastore to a compressed state in the columnstore.

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 - the operation does not apply to the deltastore. Or, the rowgroup was compressed prior to upgrading to SQL Server 2016 (13.x) in which case the history is not preserved.

2 - INDEX_BUILD - An index create or index rebuild compressed the rowgroup.

3 - TUPLE_MOVER - The tuple mover running in the background compressed the rowgroup. Tuple mover happens after the rowgroup changes state from OPEN to CLOSED.

4 - REORG_NORMAL - The reorganization operation, ALTER INDEX ... REORG, moved the CLOSED rowgroup from the deltastore to the columnstore. This occurred before the tuple-mover had time to move the rowgroup.

5 - REORG_FORCED - This rowgroup was open in the deltastore and was forced into the columnstore before it had a full number of rows.

6 - BULKLOAD - A bulk-load operation compressed the rowgroup directly without using the deltastore.

7 - MERGE - A merge operation consolidated one or more rowgroups into this rowgroup and then performed the columnstore compression.
has_vertipaq_optimization bit VertiPaq optimization improves columnstore compression by rearranging the order of the rows in the rowgroup to achieve higher compression. This optimization occurs automatically in most cases. There are two cases where VertiPaq optimization is not used:
a. when a delta rowgroup moves into the columnstore and there are one or more nonclustered indexes on the columnstore index - in this case VertiPaq optimization is skipped to minimizes changes to the mapping index;
b. for columnstore indexes on memory-optimized tables.

0 = No

1 = Yes
generation bigint Row group generation associated with this row group.
created_time datetime2 Clock time for when this rowgroup was created.

NULL - for a columnstore index on an in-memory table.
closed_time datetime2 Clock time for when this rowgroup was closed.

NULL - for a columnstore index on an in-memory table.

Results

Returns one row for each rowgroup in the current database.

Permissions

Requires CONTROL permission on the table and VIEW DATABASE STATE permission on the database.

Permissions for SQL Server 2022 and later

Requires VIEW DATABASE PERFORMANCE STATE permission on the database.

Examples

A. Calculate fragmentation to decide when to reorganize or rebuild a columnstore index.

For columnstore indexes, the percent of deleted rows is a good measure for the fragmentation in a rowgroup. When the fragmentation is 20% or more, remove the deleted rows. For more examples, see Reorganize and Rebuild Indexes.

This example joins sys.dm_db_column_store_row_group_physical_stats with other system tables and then calculates the Fragmentation column as an estimate of the efficiency of each row group in the current database. To find information on a single table, remove the comment hyphens in front of the WHERE clause and provide a table name.

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  
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;  

See Also

Object Catalog Views (Transact-SQL)
Catalog Views (Transact-SQL)
Columnstore Index Architecture
Querying the SQL Server System Catalog FAQ
sys.columns (Transact-SQL)
sys.all_columns (Transact-SQL)
sys.computed_columns (Transact-SQL)
sys.column_store_dictionaries (Transact-SQL)
sys.column_store_segments (Transact-SQL)