Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « SQL Server Proper Case FunctionMirroring: Witness misconceptions in High-Performance »
    comments

    I do not know if there is already code for table sizes (as used in SQL Server 2008 reports) but what I've seen on the net people are using cursors and temporary tables (completely unnecessary).

    NOTE (added later):
    In order to update table sizes in sys.dm_db_partition_stats you can execute next DBCC (all tables for current database):
    DBCC UPDATEUSAGE (0) WITH NO_INFOMSGS, COUNT_ROWS

    1. ;WITH SpaceUsage AS
    2. (
    3.    SELECT s.Name + '.' + o.Name AS tblName,
    4.           case when i.index_id < 2 Then row_count else 0 end AS nRows,
    5.           reserved_page_count AS Reserved,
    6.           used_page_count     AS Used,
    7.           case when i.index_id < 2 Then (in_row_used_page_count - in_row_data_page_count)
    8.                                     else  p.used_page_count end AS indUsed
    9.      FROM sys.dm_db_partition_stats p
    10.     INNER JOIN sys.objects          o ON o.object_id = p.object_id
    11.     INNER JOIN sys.schemas          s ON s.schema_id = o.schema_id
    12.      LEFT OUTER JOIN sys.indexes    i ON i.object_id = p.object_id AND i.index_id = p.index_id
    13.     WHERE o.type = 'U'
    14.       AND o.is_ms_shipped = 0
    15. )                                                  
    16. SELECT tblName AS [TABLE Name],
    17.        sum(nRows)             AS [#Records],
    18.        sum(Reserved)      * 8 AS [Reserved(KB)],
    19.        sum(Used-indUsed)  * 8 AS [DATA(KB)],
    20.        sum(indUsed)       * 8 AS [Indexes(KB)],
    21.        sum(Reserved-used) * 8 AS [Unused(KB)]
    22.   FROM SpaceUsage
    23.  GROUP BY tblName
    24.  ORDER BY [Reserved(KB)] DESC

    Here is a version with more details.

    1. ;WITH SpaceUsage AS
    2. (
    3.    SELECT s.Name + '.' + o.Name AS tblName,
    4.           Case When i.index_id = 0 then 0 else 1 end AS nInd,
    5.           case when i.index_id < 2 Then row_count else 0 end AS nRows,
    6.           used_page_count     AS Used,
    7.           reserved_page_count AS Reserved,
    8.           case when i.index_id <= 1 Then in_row_data_page_count           else 0 end AS rowUsed,
    9.           case when i.index_id <= 1 Then (in_row_used_page_count - in_row_data_page_count)
    10.                                                                           else 0 end AS cliUsed,
    11.           case when i.index_id <  1 Then p.used_page_count                else 0 end AS indUsed,
    12.           case when i.index_id <= 1 Then lob_used_page_count              else 0 end AS lobUsed,
    13.           case when i.index_id <= 1 Then row_overflow_used_page_count     else 0 end AS ofwUsed,
    14.           case when i.index_id <= 1 Then in_row_reserved_page_count       else 0 end AS rowRsvd,
    15.           case when i.index_id <= 1 Then row_overflow_reserved_page_count else 0 end AS ofwRsvd,
    16.           case when i.index_id <= 1 Then lob_reserved_page_count          else 0 end AS lobRsvd,
    17.           case when i.index_id >  1 Then reserved_page_count              else 0 end AS indRsvd
    18.      FROM sys.dm_db_partition_stats p
    19.     INNER JOIN sys.objects          o ON o.object_id = p.object_id
    20.     INNER JOIN sys.schemas          s ON s.schema_id = o.schema_id
    21.      LEFT OUTER JOIN sys.indexes    i ON i.object_id = p.object_id AND i.index_id = p.index_id
    22.     WHERE o.type = 'U'
    23.       AND o.is_ms_shipped = 0
    24. )                                                  
    25. SELECT tblName,
    26.        Sum(nInd)         AS nInd,
    27.        sum(nRows)        AS nRows,
    28.        sum(Used)     * 8 AS UsedKB,
    29.        case when sum(nRows)>0 Then (sum(Used)*8192)/Sum(nRows) else NULL end AS avgBPR,
    30.        sum(Reserved) * 8 AS ReservedKB,
    31.        sum(rowUsed)  * 8 AS rowUsedKB,
    32.        sum(cliUsed)  * 8 AS cliUsedKB,
    33.        sum(indUsed)  * 8 AS indUsedKB,
    34.        sum(lobUsed)  * 8 AS lobUsedKB,
    35.        sum(ofwUsed)  * 8 AS ofwUsedKB,
    36.        sum(rowRsvd)  * 8 AS rowRsvdKB,
    37.        sum(ofwRsvd)  * 8 AS ofwRsvdKB,
    38.        sum(lobRsvd)  * 8 AS lobRsvdKB,
    39.        sum(indRsvd)  * 8 AS indRsvdKB
    40.   FROM SpaceUsage
    41.  GROUP BY tblName
    42.  ORDER BY ReservedKB DESC

    About the Author

    User bio image
    Social SitingsTwitterLinkedInLTD RSS Feed
    1079 views
    Instapaper

    8 comments

    Comment from: Naomi Nosonovsky [Member]
    Naomi Nosonovsky Congrats on a first blog!!!!
    02/18/10 @ 13:32
    Comment from: SQLDenis [Member] Email
    SQLDenis This is very useful Nikola, thanks for posting this!
    02/18/10 @ 13:55
    Comment from: kermit [Member] Email
    Thanks buddy
    02/22/10 @ 06:36
    Comment from: Erik [Member] Email
    Erik Nikola, one thing is that this table space information will usually be outdated unless you run sp_spaceused first, with 'updateusage' as the second parameter value.

    So I would recommend putting this query into a stored procedure which runs sp_spaceused but puts its output into a temp table or table variable so the user sees nothing, then run your query.
    02/25/10 @ 11:12
    Comment from: niikola [Member] Email
    niikola If you want up to date statistics, it should be enough to run:

    DBCC UPDATEUSAGE (0) WITH NO_INFOMSGS, COUNT_ROWS

    before SELECT
    02/28/10 @ 06:21
    Comment from: Erik [Member] Email
    Erik That's good to know. It really has the same effect?
    02/28/10 @ 17:38
    Comment from: niikola [Member] Email
    niikola According to BoL updateusage parameter just triggers execution of DBCC UPDATEUSAGE:

    [ @updateusage =] 'updateusage'
    Indicates DBCC UPDATEUSAGE should be run to update space usage information. When objname is not specified, the statement is run on the whole database; otherwise, the statement is run on objname. Values can be true or false. updateusage is varchar(5), with a default of false.



    03/01/10 @ 01:51
    Comment from: Robert [Visitor]
    Robert You appear to be omitting "indexed views" which can also use a substantial portion of the space.

    o.type = 'V'
    07/13/11 @ 00:29

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)