Search code examples
sql-servert-sqldatabase-partitioningdiskspace

Table Disk Space Usage By Filegroup and Partition in MSSQLSERVER


I have partitioned tables in one MSSQLSERVER database. Can I check how the data from one table is spread over each filegroup and partition ?


Solution

  • I found a nice script for this:

    https://web.archive.org/web/20140519033945/http://williamweber.net/table-disk-space-usage-by-filegroup-and-partition/

    SELECT
        DB_NAME() AS 'DatabaseName'
        ,OBJECT_NAME(p.OBJECT_ID) AS 'TableName'
        ,p.index_id AS 'IndexId'
        ,CASE
            WHEN p.index_id = 0 THEN 'HEAP'
            ELSE i.name
        END AS 'IndexName'
        ,p.partition_number AS 'PartitionNumber'
        ,prv_left.VALUE AS 'LowerBoundary'
        ,prv_right.VALUE AS 'UpperBoundary'
        ,CASE
            WHEN fg.name IS NULL THEN ds.name
            ELSE fg.name
        END AS 'FileGroupName'
        ,CAST(p.used_page_count * 0.0078125 AS NUMERIC(18,2)) AS 'UsedPages_MB'
        ,CAST(p.in_row_data_page_count * 0.0078125 AS NUMERIC(18,2)) AS 'DataPages_MB'
        ,CAST(p.reserved_page_count * 0.0078125 AS NUMERIC(18,2)) AS 'ReservedPages_MB'
        ,CASE
            WHEN p.index_id IN (0,1) THEN p.ROW_COUNT
            ELSE 0
        END AS 'RowCount'
        ,CASE
            WHEN p.index_id IN (0,1) THEN 'data'
            ELSE 'index'
        END 'Type'
    FROM sys.dm_db_partition_stats p
        INNER JOIN sys.indexes i
            ON i.OBJECT_ID = p.OBJECT_ID AND i.index_id = p.index_id
        INNER JOIN sys.data_spaces ds
            ON ds.data_space_id = i.data_space_id
        LEFT OUTER JOIN sys.partition_schemes ps
            ON ps.data_space_id = i.data_space_id
        LEFT OUTER JOIN sys.destination_data_spaces dds
            ON dds.partition_scheme_id = ps.data_space_id
            AND dds.destination_id = p.partition_number
        LEFT OUTER JOIN sys.filegroups fg
            ON fg.data_space_id = dds.data_space_id
        LEFT OUTER JOIN sys.partition_range_values prv_right
            ON prv_right.function_id = ps.function_id
            AND prv_right.boundary_id = p.partition_number
        LEFT OUTER JOIN sys.partition_range_values prv_left
            ON prv_left.function_id = ps.function_id
            AND prv_left.boundary_id = p.partition_number - 1
    WHERE
        OBJECTPROPERTY(p.OBJECT_ID, 'ISMSSHipped') = 0
        --AND p.index_id in (0,1)
    

    Here’s a quick explanation of the data columns being pulled in, according to the author:

    By default data pages in MSSQL are 8KB and that’s the assumption that I’m making with this query.

    Used_Pages: the number of pages actually used by the table including non-leaf B-tree pages and IAM pages.
    Reserved_Pages: is the number of pages being reserved in total for the object, whether used or not.
    Data_Pages: the number of pages being used excluding non-leaf B-tree pages.
    

    here’s a link to the BOL page that describes these: msdn.microsoft.com/en-us/library/ms187737.aspx