Novick Software
SQL Server Consulting • Design • Programming • Tuning

  andy novick is a sql server mvp

 

 

SQL Server T-SQL User-Defined Function of the Week

Using fn_virtualfilestats to Get I/O Stats by Database.

Volume 1 Number 37     July 29, 2003

Check out the UDF Frequently Asked Questions at:
http://www.novicksoftware.com/UdfOfWeek/UDF_FAQ.htm

To ask a UDF related question or to contribute a UDF,
send e-mail to udf@NovickSoftware.com

Sign up for this newsletter at:
http://www.novicksoftware.com/UdfOfWeek/UDFofWeekSignup.htm

There are many ways to analyze performance of SQL Server.  In 
recent months I've written about using Perfmon and SQL Profiler
to take a look at various aspects of performance.  You'll find
one of the articles on www.DatabaseJournal.com at the link:
http://www.databasejournal.com/article.php/10888_2203601_3

SQL Server has several other ways to provide performance data
including several built-in functions and a system user-defined
function named fn_virtualfilestats.

fn_virtualfilestats returns statistics on Input/Output (I/O)
activity on a database file by database file basis.  There
are times when you might want to see it at the individual file
basis but there are times when you'd prefer that it be
aggregated at a different level.

This week's UDF aggregates the output of fn_virtualfilestats
by database.  This gives you an idea about which databases 
are the most active.

Here's the CREATE FUNCTION script:
/------- Start copying below this line -------------------------\
SET QUOTED_IDENTIFIER ON 
SET ANSI_NULLS ON 
GO

CREATE  FUNCTION dbo.udf_Perf_FS_ByDbTAB (

    @DB_Name_Pattern sysname = NULL -- LIKE name of the database
             -- to get stats for or NULL for ALL
)   RETURNS  TABLE
   -- No SCHEMABINDING due to use of system UDF
/*
* Returns a table of total statistics for one databases or
* a group of databases where the name matches a pattern. Null for
* all.  Done by grouping by database.
*
* Example:
select * from dbo.udf_Perf_FS_ByDbTAB ('pubs')
*
* © Copyright 2003 Andrew Novick http://www.NovickSoftware.com
* You may use this function in any of your SQL Server databases
* including databases that you sell, so long as they contain 
* other unrelated database objects. You may not publish this 
* UDF either in print or electronically.
* Published in the T-SQL UDF of the Week Newsletter Vol 1 #37 7/29/03
http://www.NovickSoftware.com/UDFofWeek/UDFofWeek.htm
*****************************************************************/
AS RETURN

SELECT TOP 100 PERCENT WITH TIES 
       DB_Name(DbId) [DatabaseName]-- get the name
     , DbId AS [DBID]-- ID might be useful some times
     , Count(DbId) [NumberOfFiles]-- Number of files
     , Sum(NumberReads) as [NumberReads]
     , Sum(NumberWrites) as [NumberWrites]
     , Sum(BytesRead) as [BytesRead]
     , Sum(BytesWritten) as [BytesWritten]
     , Sum(IoStallMS) as [IoStallMS]
     , Avg([TimeStamp] / 1000) as SecondsInMeasurement
   FROM ::fn_virtualfilestats(-1, -1) -- -1 for all db and files
   WHERE (@DB_Name_Pattern IS NULL
         OR db_Name(dbid) LIKE @DB_Name_Pattern)
   GROUP BY DbID
   ORDER BY Sum(NumberReads)
          + Sum(NumberWrites) desc -- Top I/O first

GO
GRANT SELECT on dbo.udf_Perf_FS_ByDbTAB to PUBLIC
GO
\-------Stop copying above this line ---------------------------/

The following query gets the file stats for pubs.  As you can
see, there hasn't been to much activity yet today.  I've used
column aliases to shorten the column names enough that the output
fits on a line.
/------- Start copying below this line -------------------------\
select DatabaseName as Name
     , NumberOfFiles as Files
     , NumberReads as Reads
     , NumberWrites as Writes
     , BytesRead
     , BytesWritten
     , IoStallMS
     , SecondsInMeasurement as Sec
    FROM dbo.udf_Perf_FS_ByDbTAB ('pubs')
GO        
\-------Stop copying above this line ---------------------------/
(Results)
Name  Files  Reads Writes BytesRead BytesWritten IoStallMS    Sec
----- ------ ----- ------ --------- ------------ --------- ------
pubs       2    25      8   1327104        96768      2170   5851

The parameter isn't just one name.  You can use NULL to get
the results for all database or a pattern that works with the
LIKE operator to get several databases as in this query:

/------- Start copying below this line -------------------------\
select DatabaseName as Name
     , NumberOfFiles as Files
     , NumberReads as Reads
     , NumberWrites as Writes
     , BytesRead
     , BytesWritten
     , SecondsInMeasurement as Sec
    FROM dbo.udf_Perf_FS_ByDbTAB ('TSQL%')
GO
\-------Stop copying above this line ---------------------------/
(Results)
Name            Files  Reads Writes BytesRead BytesWritten Sec
--------------- ------ ----- ------ --------- ------------ ------
TSQLWorking          2    34      8    872448       156672    252
TSQLUDFS             2    21      6   1003520       139264    252
TSQLFunctions5       2    17      8    741376       156672    252

fn_virtualfilestats only shows statistics accumulated since the
SQL Server Instance started.  The Sec column tells you how long
that's been.

As you can see, my server was just rebooted.  The numbers
get more interesting when it's been up for a while.

My next article on Database Journal contains code that accumulates
the results of fn_virtualfilestats over time so that you can get 
a look at what's happening at peak database usage time periods, 
when they really count.


RSS as HTML

Personal Blog

 
New Tips:

Use dsinit to set the SQL Server instance for Windows Azure dev storage

Upcoming
Presentations:

Code Camp 14
Oct 2, 2010
Data Dude
SQL Azure


Full Schedule