September 12, 2013

Measure Transactions Per Second in SQL Server

Performance Monitor tool in SQL Server represents aspects of system performance, such as CPU Usage % , Memory Paging etc. The sys.dm_os_performance_counters Dynamic Management View exposes data of all performance counters for the particular instance of SQL Server. This view is extremely useful when you have to present the performance data of your database in your dashboard.

We have touched upon the usefulness of the sys.dm_os_performance_counters in my previous post Removing Deprecated Code and Future Proofing your Queries. In this post, we will see another use of the sys.dm_os_performance_counters view to measure SQL transactions per second for a database. Here’s a very handy query written by Joe Stefanelli

DECLARE @ctr bigint
SELECT @ctr = ctr
    FROM sys.dm_os_performance_counters
    WHERE counter_name = 'transactions/sec'
        AND object_name = 'SQLServer:Databases'
        AND instance_name = 'SomeDBName'
WAITFOR DELAY '00:00:01'
SELECT ctr - @ctr
    FROM sys.dm_os_performance_counters
    WHERE counter_name = 'transactions/sec'
        AND object_name = 'SQLServer:Databases'
        AND instance_name = 'SomeDBName'

As you can see, were taking the difference of two values for a delay of one second to get the number of transactions per second. In future posts, we will see some more queries using this useful DMV.


About The Author

Suprotim Agarwal, ASP.NET Architecture MVP works as an Architect Consultant and provides consultancy on how to design and develop Web applications.

Suprotim is also the founder and primary contributor to DevCurry, DotNetCurry and SQLServerCurry. He has also written an EBook 51 Recipes using jQuery with ASP.NET Controls.

Follow him on twitter @suprotimagarwal

5 comments:

Phrenetic Phil said...

I'm a bit puzzled by this. As I understand it, you are getting the transactions per second from one database, waiting a second, and then and subtracting this from the transactions per second from another database. The MSDN description for the counter is 'Number of transactions started for the database per second.' so why would you need to calculate the difference in TPS between two different databases (or even the same one) after a second?

Anonymous said...

Script will not run. Get:

Msg 207, Level 16, State 1, Line 2
Invalid column name 'ctr'.
Msg 207, Level 16, State 1, Line 8
Invalid column name 'ctr'.

Suprotim Agarwal said...

@Phrenetic Phil - When you say "per seconds" it refers to a cumulative value. Silly me, the databases are not two, that was a typo :p. Fixed!

JFoushee said...

Also got the "Invalid column name 'ctr'." error. Is this what you mean to say?

DECLARE @dbname varchar(128); SET @dbname = 'DBAWeb4'
DECLARE @cntr_value bigint

SELECT @cntr_value = cntr_value
FROM sys.dm_os_performance_counters
WHERE counter_name = 'transactions/sec'
AND object_name = 'SQLServer:Databases'
AND instance_name = @dbname

WAITFOR DELAY '00:00:01'

SELECT cntr_value - @cntr_value
FROM sys.dm_os_performance_counters
WHERE counter_name = 'transactions/sec'
AND object_name = 'SQLServer:Databases'
AND instance_name = @dbname

CNG said...

Transactions Per second:


SELECT
datepart(year, utcdate) as yy,
datepart(month, utcdate) as mon,
datepart(day, utcdate) as dd,
datepart(hour, utcdate) as hh,
datepart(minute, utcdate) as mm,
datepart(second, utcdate) as ss,
count(*) AS TPS
FROM [YourDB].[dbo].[target_table] (nolock)
where utcdate >= '2014-01-27 18:00'
and utcdate < '2014-01-27 19:30'
group by
datepart(day, utcdate),
datepart(month, utcdate),
datepart(year, utcdate),
datepart(hour, utcdate),
datepart(minute, utcdate),
datepart(second, utcdate)
order by yy, mon, dd, hh, mm, ss DESC