Monitoring Table Size Growth in SQL Server
In this article I introduce a simple process that saves tables
size information at points in time which latter allows for tracking down table
growth over time.
The process is useful in monitoring data growth over time and lets
you see what tables are growing rapidly in what databases and can also help in
estimating future growth and disk space requirements. In addition it can help
prevent unexpectedly running out of disk space, or if you are already in
that situation then quickly find the table(s) that for some reason have grown
more than excepted and are the source to the problem.
In addition, I also show a stored procedure called sp_DataFiles that returns a report of disk space usage
information at the data file level.
Run these three scripts:
The process is built on top of a stored procedure called
sp_TableSize which returns table level information such as row count and size.
Periodically, typically by a weekly SQL Server Agent job, the procedure
will be executed against all databases using an INSERT…EXEC statement that saves the results into a database table.
Having done that we actually freeze and document size related
information at the table level which can now be analyzed and so the next and
final step would be to retrieve the data.
There are two main scenarios in which you can benefit from the
One scenario is simply viewing the report knowing what tables grow
in what size and that rate at which they grow.
The second scenario would be to execute the DataGrowth stored
procedure while passing the @Delta_MB input parameter a value that is not
expected to be reached so that it always returns an empty result set. Now, when
the day comes and this procedure returns data you know there was a growth in
data exceeding your predefined threshold and can trigger a notification email.
Summary of scripts used:
TableSizeHistory.sql – Creates the PerfDB database and the TableSizeHistory table
DataGrowth.sql – Analyzes and retrieves the captured data
ExecuteDatabasesCommand.sql – A wrapper over a database cursor
sp_DataFiles.sql – Returns size information at the data file level for all
sp_TableSize.sql – Returns table level information for the current database
sp_TableSize is a stored procedure
created in the master database and marked as a system stored procedure. The
procedure works at the table level in the context of the current database, that
is the database where it is executed from and returns one row per table with
the information of the row count and disk space usage in units of MB sorted by
disk space usage in a descending order.
The procedure is handy and easy to use with no input
parameters required and the information returned is based on system meta data,
meaning you do not actually access any user object so there is no effect (no
shared locks and no IO) on user objects as opposed to issuing a COUNT(*) query.
Bare in mind that due to the above fact there may
be a slight(minor)inaccuracy with the row count figure but that is not
common and results from the way SQL Server’s Storage Engine keeps track of data
that was deleted and typically gets aligned with the accurate figure following
a clustered index rebuild.
Part of the code in sp_TableSize is combined in my
This stored procedure analyzes and retrieves the data that
was saved to the TableSizeHistory table using the sp_TableSize stored
procedure and returns the disk space growth in units of MB per each table.
The code identifies the first and last occurrences of
each table in the requested time period as defined by the @StartTime and
@EndTime input parameters and calculates the differences between the two occurrences
so that the returned result set is the delta between these two values.
You can control the tables returned by the @Delta_MB
input parameter so that you get to see only tables of interest, i.e. tables
that grew more than a certain size.
The Delta_reserved_MB column is the sum of the
Delta_data_MB + Delta_index_size_MB and this is the actual disk size the table
uses. Don’t let the name confuse you, I only followed Microsoft’s terminology
used in their sp_spaceused system stored procedure.
The @Database parameter has a default value of 1 and
returns a second result set with information at the database level.
This procedure is actually a wrapper over a cursor that
uses the database name from sys.databases DMV.
I created this procedure in order to reuse my code so that
every time I need a cursor over databases I use it instead of recoding that
cursor part. i.e. when I run an index rebuild process that uses my sp_Reindex
procedure, DBCC commands for integrity checks, attach, detach etc.
This stored procedure is not related to the data growth process but
is a very useful disk space related tool.
sp_DataFiles works at the database level and returns one row per each data
file on the SQL Server instance.
The procedure is actually built on top of the disk
usage report query issued by SSMS (SQL Server Management Studio) which I
captured in Profiler a couple of years a go and adjusted a little for my needs. Being able to get that report by
executing a procedure is far more convenience and efficient than going through
the entire process required via the UI until finally receiving that desired
report and also, the SSMS report works on a specific database and when you need
to get a more wider picture of how your disk space is consumed by your
databases it is not enough.
The procedure makes use of the undocumented
DBCC command SHOWFILESTATS which returns the total extents and the used
extents information per data file and joins that information with the
sys.data_spaces DMV (Dynamic Management View).
All the disk space figures are calculated and derived
from the extent information returned by the DBCC command while the DMV only
contributes the file group name to the returned results.
DBCC SHOWFILESTATS returns one row per each data file in the database and sys.data_spaces returns one row per each data
space (which can actually be a filegroup, partition scheme, or FILESTREAM data
The procedure also returns the space reserved and space used
information which is very useful. When these two figures are far from each other
(i.e. a data file that stores 10GB of data but reserves 40GB) there is space
that can be reclaimed to the operating system if needed.
On the other hand when these two figures are close to
each other it points out that the file Auto Grow option is kicking in and that
of course is something we usually want to avoid.
Pages: 1 2