SQL Server : Get size of all tables in database

T.Zacks 3,996 Reputation points
2021-07-11T08:28:44.977+00:00

The above sql works fine but i want the size in KB OR MB OR GB at the end i want a new column which show total size like TableSizeInMB+IndexSizeInMB KB OR MB OR GB

;with cte as (
SELECT
t.name as TableName,
SUM (s.used_page_count) as used_pages_count,
SUM (CASE
            WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
            ELSE lob_used_page_count + row_overflow_used_page_count
        END) as pages
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.tables AS t ON s.object_id = t.object_id
JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id
GROUP BY t.name
)
select
    cte.TableName, 
    cast((cte.pages * 8.)/1024 as decimal(10,3)) as TableSizeInMB, 
    cast(((CASE WHEN cte.used_pages_count > cte.pages 
                THEN cte.used_pages_count - cte.pages
                ELSE 0 
          END) * 8./1024) as decimal(10,3)) as IndexSizeInMB
from cte
order by 2 desc

thanks

Developer technologies | Transact-SQL
Developer technologies | Transact-SQL
A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
{count} votes

Answer accepted by question author
  1. EchoLiu-MSFT 14,626 Reputation points
    2021-07-13T07:01:44.06+00:00

    Try:

      ;with cte as (  
      SELECT  
      t.name as TableName,  
      SUM (s.used_page_count) as used_pages_count,  
      SUM (CASE  
                  WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)  
                  ELSE lob_used_page_count + row_overflow_used_page_count  
              END) as pages  
      FROM sys.dm_db_partition_stats  AS s   
      JOIN sys.tables AS t ON s.object_id = t.object_id  
      JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id  
      GROUP BY t.name  
      )  
      ,cte2 as(select  
          cte.TableName,   
          (cte.pages * 8.) as TableSizeInKB,   
          ((CASE WHEN cte.used_pages_count > cte.pages   
                      THEN cte.used_pages_count - cte.pages  
                      ELSE 0   
                END) * 8.) as IndexSizeInKB  
      from cte  
     )  
     select TableName,TableSizeInKB,IndexSizeInKB,  
     case when (TableSizeInKB+IndexSizeInKB)>1024*1024   
     then cast((TableSizeInKB+IndexSizeInKB)/1024*1024 as varchar)+'GB'  
     when (TableSizeInKB+IndexSizeInKB)>1024   
     then cast((TableSizeInKB+IndexSizeInKB)/1024 as varchar)+'MB'  
     else cast((TableSizeInKB+IndexSizeInKB) as varchar)+'KB' end [TableSizeIn+IndexSizeIn]  
     from cte2  
     order by 2 desc  
    

    114102-image.png

    4 people found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Viorel 125.7K Reputation points
    2021-07-11T20:22:37.78+00:00

    Maybe you want this formatting of total size:

    ;with cte as (
    SELECT
    t.name as TableName,
    SUM (s.used_page_count) as used_pages_count,
    SUM (CASE
                WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
                ELSE lob_used_page_count + row_overflow_used_page_count
            END) as pages
    FROM sys.dm_db_partition_stats  AS s 
    JOIN sys.tables AS t ON s.object_id = t.object_id
    JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id
    GROUP BY t.name
    ), 
    cte2 as
    (
    select
        cte.TableName, 
        cast((cte.pages * 8.) as decimal(10,3)) as TableSizeInKB, 
        cast(((CASE WHEN cte.used_pages_count > cte.pages 
                    THEN cte.used_pages_count - cte.pages
                    ELSE 0 
              END) * 8.) as decimal(10,3)) as IndexSizeInKB
    from cte
    )
    select TableName, TableSizeInKB, IndexSizeInKB,
        case 
           when s > 1024 * 1024 then format(s / 1024 / 1024, '0.###'' GB''')
           when s > 1024 then format(s / 1024, '0.###'' MB''')
           else format(s, '0.###'' KB''') end as [TableSize + IndexSize]
    from cte2
    cross apply (values (TableSizeInKB + IndexSizeInKB)) t(s)
    order by s desc
    
    2 people found this answer helpful.

  2. EchoLiu-MSFT 14,626 Reputation points
    2021-07-12T02:35:39.25+00:00

    Please also check:

     ;with cte as (
     SELECT
     t.name as TableName,
     SUM (s.used_page_count) as used_pages_count,
     SUM (CASE
                 WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
                 ELSE lob_used_page_count + row_overflow_used_page_count
             END) as pages
     FROM sys.dm_db_partition_stats  AS s 
     JOIN sys.tables AS t ON s.object_id = t.object_id
     JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id
     GROUP BY t.name
     )
     ,cte2 as(select
         cte.TableName, 
         cast((cte.pages * 8.) as decimal(10,3)) as TableSizeInKB, 
         cast(((CASE WHEN cte.used_pages_count > cte.pages 
                     THEN cte.used_pages_count - cte.pages
                     ELSE 0 
               END) * 8.) as decimal(10,3)) as IndexSizeInKB
     from cte
    )
    select TableName,TableSizeInKB,IndexSizeInKB,
    case when (TableSizeInKB+IndexSizeInKB)>1024*1024 
    then cast((TableSizeInKB+IndexSizeInKB)/1024*1024 as varchar)+'GB'
    when (TableSizeInKB+IndexSizeInKB)>1024 
    then cast((TableSizeInKB+IndexSizeInKB)/1024 as varchar)+'MB'
    else cast((TableSizeInKB+IndexSizeInKB) as varchar)+'KB' end [TableSizeIn+IndexSizeIn]
    from cte2
    order by 2 desc
    

    If you have any question, please feel free to let me know.

    Regards
    Echo


    If the answer is helpful, please click "Accept Answer" and upvote it.

    1 person found this answer helpful.

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.