Dieses Blog durchsuchen

Donnerstag, 2. Juli 2015

Expensive Queries - die Performancebremser

Von Zeit zu Zeit will man wissen, welche Statements gegen die Datenbanken abgesetzt wurden und sehr viel Ressourcen verbraucht haben. Anhand dieser Information kann man unter Umständen einen Performanceverbesserung ableiten, oder auch fehlerhafte Queries, welche nicht restriktiv genug einschränken ausfindig machen.
Natürlich ist es auch wichtig, wie oft ein Statement ausgeführt wurde. Denn ein Statement, dass zB 10000 mal ausgeführt wurde, jedoch jeweils nur sehr wenig CPU Zeit und IO benötigt hat, stört kaum. Falls ein Statement oft ausgeführt wird und eine Optimierung möglich ist, kann auf einfachem Wege eine Entlastung von CPU, IO etc erreicht werden.


/*
 Skript listet die "teuersten" Queries, des letzten Monats auf
 - über die Variable @MinDurchfuehr kann gsqlstatementeuert werden, 
   ab wievielen Durchführungen eine Query berücksichtigt wird.
 - über die Variable @Tage kann der Zeitraum gesteuert werden
   es werden die letzten @Tage ausgewertet 
*/

DECLARE @MinDurchfuehr int = 5; 
DECLARE @Tage int = 100;
 
SELECT querystats.total_worker_time AS SummeArbeitszeit 
      ,querystats.total_logical_reads + querystats.total_logical_writes AS SummeLogicalIO 
   ,querystats.total_worker_time / querystats.execution_count as DurchschnCPUZeit 
      ,(querystats.total_logical_reads + querystats.total_logical_writes) / querystats.execution_count AS DurchschnLogicalIO 
      ,querystats.execution_count As AnzahlAusfuehrung 
      ,querystats.last_execution_time AS LetzteDurchfuehrung
      ,DB.name AS Datenbank 
      ,SUBSTRING(sqlstatement.text,1 + querystats.statement_start_offset / 2 
                   ,(CASE WHEN querystats.statement_end_offset = -1  
                          THEN LEN(convert(nvarchar(max), sqlstatement.text)) * 2  
                          ELSE querystats.statement_end_offset 
        END  
                       - querystats.statement_start_offset) / 2 
                ) AS SqlStatement 
      -- Optionale Anzeige des Query Plans - wenn einkommentiert, dann läuft die Query viel länger!
      --,queryplan.[query_plan] AS [QueryPlan] 
FROM sys.dm_exec_query_stats AS querystats 
CROSS APPLY sys.dm_exec_sql_text(querystats.sql_handle) AS sqlstatement 
--Wenn Query Plan benötigt, dann auch diese Zeile einkommentieren
--CROSS APPLY sys.dm_exec_query_plan(querystats.plan_handle) AS queryplan 
LEFT JOIN sys.databases AS DB 
  ON sqlstatement.dbid = DB.database_id      
WHERE querystats.execution_count > @MinDurchfuehr 
      AND querystats.last_execution_time > DATEADD(DAY, (@Tage * -1), GETDATE()) 
ORDER BY SummeArbeitszeit DESC 
        ,SummeLogicalIO DESC


Keine Kommentare:

Kommentar veröffentlichen