A partire dal SQL Server 2008 R2, fare analisi sulle performance dei reporting services è diventato ancora più semplice con l’aggiunta, all’interno del database ReportServer (o ReportServer$<nome istanza>), della vista [ExecutionLog3].

In questa vista, tre sono le informazioni in grado di farci analizzare i tempi necessari a generare un report:

  1. TimeDataRetrieval: millisecondi utilizzati per recuperare i dati del report (apertura delle connessioni, lettura delle righe, popolamento di tutti i dataset del report – anche quelli che, eventualmente, sono stati definiti ma non vengono in realtà utilizzati per visualizzare dati)
  2. TimeProcessing:  millisecondi utilizzati dal motore di report per la richiesta (filtri, ordinamenti, raggruppamenti, …)
  3. TimeRendering: millisecondi per visualizzare il report (risoluzione delle espressioni presenti all’interno del report, definizione paginazioni, render della pagina da mostrare a video)

In sostanza potremmo definire questa equazione:

TempoTotale = TimeDataRetrieval + TimeProcessing + TimeRendering

Se volessi trovare i dieci report più lenti, come tempo totale, potrei quindi scrivere qualcosa come:

WITH myQuery
    AS ( SELECT TOP 10 ItemPath , 
                       TimeDataRetrieval + TimeProcessing + TimeRendering AS [TotalTime ms]
           FROM ExecutionLog3 )
    SELECT 
       ItemPath,
       [TotalTime ms],
       ([TotalTime ms]/1000.0) as [TotalTime sec]
      FROM myQuery
      ORDER BY [TotalTime ms] DESC;

image

Quali azioni posso considerare per diminuire eventuali alti tempi di elaborazione?

  • Recupero dei dati
    • verificare la presenza di dataset non necessari
    • recuperare solo le righe / colonne effettivamente necessarie al report
    • utilizzare SQL Server Profiler (naturalmente se la sorgente dati è SQL Server) per analizzare tempi di esecuzione di ogni singola query
    • ricordarsi che un solo dataset può essere usato per più dataregion (tablix, chart, gauge, …) :-)
  • Processing
    • maggiore è il numero di oggetti da processare sul report (tablix, chart, gauge, …) maggiore sarà il tempo totale
    • prendere in considerazione la possibilità di effettuare ordinamenti e raggruppamenti sul db engine (SQL Server è spesso più veloce del motore dei reporting)
  • Rendering
    • come sopra. Maggiore è il numero di oggetti, maggiore sarà il tempo di render

 

La vista [ExecutionLog3], oltre a quanto sopra, può essere utilizzata per una serie di analisi utili a comprendere il reale utilizzo della soluzione di reportistica.

Qualche esempio…

Report richiamati in un giorno

DECLARE @d date = '20120731';
WITH myQuery
    AS ( SELECT CAST( timestart AS date )AS reportDate , 
                ItemPath
           FROM ExecutionLog3
           WHERE ItemPath != '' )
    SELECT COUNT( reportDate )AS Nr , 
           reportDate , 
           ItemPath
      FROM myQuery
      WHERE reportDate = @d
      GROUP BY reportDate , 
               ItemPath
      ORDER BY COUNT( reportDate )DESC;

image

Utenti più attivi negli ultimi trenta giorni

SELECT  
    UserName,
    COUNT(1) AS Nr
FROM    ExecutionLog3
WHERE  TimeStart > GETDATE() - 30
GROUP BY UserName
ORDER BY COUNT(1) DESC

image

Prima / ultima e numero di esecuzioni

SELECT MIN( dbo.ExecutionLog3.TimeStart ) AS [First Execution] , 
       MAX( dbo.ExecutionLog3.TimeStart ) AS [Last Execution] , 
       COUNT( dbo.ExecutionLog3.TimeStart ) AS Nr , 
       ItemPath
  FROM dbo.ExecutionLog3
  WHERE Status = 'rsSuccess' AND ItemPath != ''
  GROUP BY ItemPath
  ORDER BY Nr desc;

image