Solved

Need to tweak sql query

Posted on 2011-02-16
3
481 Views
Last Modified: 2012-05-11
Hi,

I have a query which populates a table called pcms_sql_cache - the definition is below for the table;
The table gets populated by the query i have below;
What i need to do is run the sql hourly to populate the table from a sql job then raise an alert if the
column avg_recent_duration is greater than 5sec;
How should the sql be changed to run and check the column avg_recent_duration;
Please help - the sql looks worse than it is !

thanks

CREATE TABLE [dbo].[pcms_sql_cache](
      [ID] [int] IDENTITY(1,1) NOT NULL,
      [Timestamp] [datetime] NULL,
      [database_name] [varchar](20) NOT NULL,
      [statement_text] [varchar](5000) NOT NULL,
      [cache_creation_time] [datetime] NOT NULL,
      [total_execution_count] [bigint] NOT NULL,
      [total_cpu_time] [bigint] NOT NULL,
      [total_elapsed_time] [bigint] NOT NULL,
      [total_recent_time] [bigint] NULL,
      [total_recent_executions] [bigint] NULL,
      [avg_recent_duration] [bigint] NULL
) ON [PRIMARY]

INSERT INTO pcms_sql_cache
SELECT TOP 1
   GETDATE() as timestamp
   ,   DB_Name(qp.dbid) as database_name
   , SUBSTRING(qt.text, (qs.statement_start_offset/2) + 1,
        ((CASE statement_end_offset
            WHEN -1 THEN DATALENGTH(qt.text)
            ELSE qs.statement_end_offset END
                - qs.statement_start_offset)/2) + 1) as statement_text    
                , qs.creation_time as cache_creation_time
                , qs.execution_count
    , qs.total_worker_time as total_cpu_time
    , qs.total_elapsed_time
    , CASE WHEN (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))) >=0
      THEN  (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))) ELSE NULL END as total_recent_time
    , (qs.execution_count - (select total_execution_count from pcms_sql_cache where ID=(select max(ID) from pcms_sql_cache))) as

total_recent_executions
   , (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache)))/    
   NULLIF((qs.execution_count - (select total_execution_count from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))),0) as

avg_recent_duration
    FROM sys.dm_exec_query_stats as qs
    CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) as qp
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
     Where DB_Name(qp.dbid) = 'Autopart'
     and (SUBSTRING(qt.text, (qs.statement_start_offset/2) + 1,
        ((CASE statement_end_offset
            WHEN -1 THEN DATALENGTH(qt.text)
            ELSE qs.statement_end_offset END
                -qs.statement_start_offset)/2) + 1)) LIKE 'Select top 100%';
0
Comment
Question by:hraja77
  • 2
3 Comments
 
LVL 7

Accepted Solution

by:
tlovie earned 500 total points
ID: 34908419
you could create a stored procedure that would do something like this and run it in a job:

create procedure spPCMS_SQL_CACHE as

declare @timestamp datetime
select @timestamp=getdate()

INSERT INTO pcms_sql_cache
SELECT TOP 1
   @timestamp
   ,   DB_Name(qp.dbid) as database_name
   , SUBSTRING(qt.text, (qs.statement_start_offset/2) + 1,
        ((CASE statement_end_offset
            WHEN -1 THEN DATALENGTH(qt.text)
            ELSE qs.statement_end_offset END
                - qs.statement_start_offset)/2) + 1) as statement_text    
                , qs.creation_time as cache_creation_time
                , qs.execution_count
    , qs.total_worker_time as total_cpu_time
    , qs.total_elapsed_time
    , CASE WHEN (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))) >=0
      THEN  (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))) ELSE NULL END as total_recent_time
    , (qs.execution_count - (select total_execution_count from pcms_sql_cache where ID=(select max(ID) from pcms_sql_cache))) as

total_recent_executions
   , (qs.total_elapsed_time - (select total_elapsed_time from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache)))/    
   NULLIF((qs.execution_count - (select total_execution_count from pcms_sql_cache where ID=(select max(ID)from pcms_sql_cache))),0) as

avg_recent_duration
    FROM sys.dm_exec_query_stats as qs
    CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) as qp
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
     Where DB_Name(qp.dbid) = 'Autopart'
     and (SUBSTRING(qt.text, (qs.statement_start_offset/2) + 1,
        ((CASE statement_end_offset
            WHEN -1 THEN DATALENGTH(qt.text)
            ELSE qs.statement_end_offset END
                -qs.statement_start_offset)/2) + 1)) LIKE 'Select top 100%';


if exists (select * from pcms_sql_cache where timestamp=@timestamp and avg_recent_duration>5)
     exec MSDB.dbo.sp_send_dbmail @recipients='you@youremail.com;somebodyelse@youremail.com', @subject='Longer run times experienced', @body='whatever you want here'
0
 
LVL 1

Author Comment

by:hraja77
ID: 34908553
so far so good - but just aquick one - if the 'IF' statement is true i want to just make the sql server job fail - how would i do this ?

thanks
H
0
 
LVL 7

Expert Comment

by:tlovie
ID: 34908620
you'd have to change the if block to this:  


if exists (select * from pcms_sql_cache where timestamp=@timestamp and avg_recent_duration>5)
     begin
     exec MSDB.dbo.sp_send_dbmail @recipients='you@youremail.com;somebodyelse@youremail.com', @subject='Longer run times experienced', @body='whatever you want here'
     raiserror('Raiserror statement', 16, 1);
     end
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
Use this article to create a batch file to backup a Microsoft SQL Server database to a Windows folder.  The folder can be on the local hard drive or on a network share.  This batch file will query the SQL server to get the current date & time and wi…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.

816 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now