Re-purpose my TableSize Script

Comments: No Comments
Published on: March 3, 2011

Last Year I introduced a couple of scripts that I worked on.  Those scripts developed into a series covering the comparison of some methods and MS provided stored procs that could help you in the retrieval of table sizes in SQL Server.

I pulled out one of those scripts recently in order to find what tables, in an R and D database, were consuming alot of space.  While running that script, I realized that it could easily be used to help me with an additional task.  I decided that this script could help me deduce the top 10 biggest tables in a database that doesn’t necessarily need to have that data.  Or maybe, I just need to clean out the data so I can test populating the database.  This script is predicated on a lack of foreign keys – but can easily be adapted.

So, in all of its glory:

/*similar to sp_spaceused */
 
DECLARE @dbsize DECIMAL(19,2)
		,@logsize DECIMAL(19,2)
 
SET NOCOUNT ON
 
/*
**  Summary data.
*/
BEGIN
	SELECT @dbsize = SUM(CONVERT(DECIMAL(19,2),CASE WHEN type = 0 THEN SIZE ELSE 0 END)) * 8/1024
		, @logsize = SUM(CONVERT(DECIMAL(19,2),CASE WHEN type = 1 THEN SIZE ELSE 0 END)) * 8/1024
		FROM sys.database_files
 
END
/*
**  We want all objects.
*/
BEGIN
	WITH FirstPass AS (
		SELECT OBJECT_ID,
			ReservedPage = CONVERT(DECIMAL(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = CONVERT(DECIMAL(19,2),SUM(used_page_count)) *8/1024,
			PageCnt = SUM(
			CONVERT(DECIMAL(19,2),CASE
				WHEN (index_id < 2)
					THEN (used_page_count)
				ELSE lob_used_page_count + row_overflow_used_page_count
				END
			)) * 8/1024,
			RowCnt = SUM(
			CASE
				WHEN (index_id < 2)
					THEN row_count
				ELSE 0
			END
			)
		FROM sys.dm_db_partition_stats
		--Where OBJECTPROPERTY(OBJECT_ID,'IsMSShipped') = 0
		GROUP BY OBJECT_ID
	)
	,InternalTables AS (
		SELECT ps.OBJECT_ID,
			ReservedPage = CONVERT(DECIMAL(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = CONVERT(DECIMAL(19,2),SUM(used_page_count)) *8/1024
		FROM sys.dm_db_partition_stats  ps
			INNER Join sys.internal_tables it
				ON it.OBJECT_ID = ps.OBJECT_ID
				And it.internal_type IN (202,204,211,212,213,214,215,216)
		WHERE it.parent_id = ps.OBJECT_ID
			--And OBJECTPROPERTY(ps.OBJECT_ID,'IsMSShipped') = 0
		GROUP BY ps.OBJECT_ID
	)
SELECT 'Truncate table ' + OBJECT_NAME (f.OBJECT_ID) + '' AS TruncTabStatement
			,TableSizeMB = SUM(f.PageCnt) +
					SUM(CASE WHEN (f.UsedPage + IsNull(i.UsedPage,0)) > f.PageCnt
						THEN ((f.UsedPage + IsNull(i.UsedPage,0)) - f.PageCnt) ELSE 0 END)
	FROM FirstPass F
		LEFT Outer Join InternalTables i
			ON i.OBJECT_ID = f.OBJECT_ID
	WHERE OBJECTPROPERTY(f.OBJECT_ID,'IsMsShipped') = 0
	GROUP BY f.OBJECT_ID
	ORDER BY TableSizeMB DESC
 
END

I think the script, along with prior explanations, is pretty straight forward.  This can quickly help reset those LARGE tables for continued testing.  Of course, that is predicated on you not already having a script for that, and that you don’t know what tables need to be reset (maybe you are in a large team).

This is just one example of a script that can be useful for more than what it was first designed to do.  As DB professionals, we often come across situations were a prior script can easily be repurposed for the task at hand.  Knowing that, and how to do it, is an important tool in your toolbox.

No Comments - Leave a comment

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>






Calendar
March 2011
M T W T F S S
« Feb   Apr »
 123456
78910111213
14151617181920
21222324252627
28293031  
Content
SQLHelp

SQLHelp


Welcome , today is Sunday, April 20, 2014