SQL Server Development Bookmark and Share   
 index > SQL Server Database Engine > Monitoring activity with sys.dm_exec_query_stats
 

Monitoring activity with sys.dm_exec_query_stats

I need to monitor activity on many different SQL Server instances that vary between SQL Server 2005 and 2008.  I am looking for a simple way to get some stats on the queries that are run; due to the requirements, this data will be encoded in an email and sent to a collection point.

I was thinking of using sys.dm_exec_query_stats, because all I really want is the logical and physical reads, the logical writes, the CPU time and the total run time of the query.  The query itself isn't important, however an application string id would be nice.  However, this view is a summary table and only contains the last query that has been run.  Is there some way to gather this information at a more granular level so I do not have to run the query once every minute?
Justin A Rush  Monday, October 12, 2009 2:18 PM
I opted to attack this with a stored procedure that runs every minute or so and snaps what is in the sql cache.  However, now I am having an issue -- I only want the stats for queries in a certain database on the server.  When I cross apply the sys.dm_exec_query_stats to sys.dm_exec_sql_text, the dbid column in the sql text table is null most of the time.  For example:

select * from sys.dm_exec_query_stats q cross apply sys.dm_exec_sql_text(q.sql_handle) query
where text like '%fact%'

I want to do something like:
select * from sys.dm_exec_query_stats q cross apply sys.dm_exec_sql_text(q.sql_handle) query
where query.dbid = db_id('my_database')

What is going on here?
Justin A Rush  Monday, October 12, 2009 7:34 PM
From MSDN it looks like the database id will not be populated if the query is ad-hoc or prepared.  I take the first one as run from SSMS and the 2nd one as run from some sort of tool.  So what it logs the database id for is beyond me.  If anyone knows the details, or a way to get the database id for a query that was run regardless of how, I would love to hear it.

Right now, here is what I am doing:
alter procedure DB_QUERY_HISTORY(@mins_ago int)
as
set @mins_ago = @mins_ago * -1
insert into DB_QUERY_HISTORY
select
	max(cur.last_execution_time),
	cur.sql_handle,
	sum(cur.execution_count),
	sum(cur.last_worker_time) cpu_time_microseconds,
	sum(cur.last_elapsed_time) run_time_microseconds,
	sum(cur.last_physical_reads) physical_reads,
	sum(cur.last_logical_writes) logical_writes,
	sum(cur.last_logical_reads) logical_reads
from
	sys.dm_exec_query_stats cur left outer join DB_QUERY_HISTORY hist
		on cur.sql_handle = hist.sql_handle
		and cur.last_execution_time = hist.last_execution_time
where
	cur.last_execution_time > DATEADD(minute,@mins_ago,getdate())
	and hist.last_execution_time is null
group by cur.sql_handle


create table DB_QUERY_HISTORY(
	last_execution_time datetime not null,
	sql_handle varbinary(64) not null,
	execution_count bigint,
	cpu_time_microseconds bigint,
	run_time_microseconds bigint,
	physical_reads bigint,
	logical_writes bigint,
	logical_reads bigint,
	primary key (last_execution_time,sql_handle)
)
However, this leaves me with loads of garbage in the table, mainly from SSRS and SQL Agent.  But it will get what I want, for the most part.
Justin A Rush  Monday, October 12, 2009 8:12 PM
The only way to get what you are looking for is to setup a trace.
Tom Phillips  Monday, October 12, 2009 8:37 PM

You can use google to search for other answers

Custom Search

More Threads

• Performance effect of the same query in SQL 2005 Express & workgroup Servers
• Comparing two datetime in SQL server gives wrong result
• Deadlock(s) and parametrized query
• mysterious space loss
• Length Limit on @database_name for sp_add_jobstep
• Changing date before 1753
• avg_fragmentation_in_percent didn't change after index rebuilt
• LazyWriter: warning, no free buffers found -
• Problemas para Subir o SQL Server CLuster
• deploy SQL Server 2005 maintenance plans.