Solved

Need to tweak sql query

Posted on 2011-02-16
3
489 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Database Solutions Engineer FAQs

In this series, we will discuss common questions received as a database Solutions Engineer at Percona. In this role, we speak with a wide array of MySQL and MongoDB users responsible for both extremely large and complex environments to smaller single-server environments.

Question has a verified solution.

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

Confronted with some SQL you don't know can be a daunting task. It can be even more daunting if that SQL carries some of the old secret codes used in the Ye Olde query syntax, such as: (+)     as used in Oracle;     *=     =*    as used in Sybase …
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

635 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