Disclaimer evidente: lavoro per SQL Sentry .
I maggiori problemi che abbiamo sono:
- Come dice @JNK, SQL Server offusca l'uso di un UDF e fa comunque cose terribili con loro (come stima sempre una riga). Quando generi un piano reale in SSMS, non ne vedi nemmeno il suo utilizzo. Siamo soggetti alle stesse limitazioni perché possiamo fornire solo le informazioni su un piano che SQL Server ci fornisce.
- Facciamo affidamento su diverse fonti per le metriche di runtime durante la generazione di un piano reale. Sfortunatamente il piano XML non include le chiamate di funzione e SQL Server non rivela l'I / O sostenuto da una funzione durante l'utilizzo di
SET STATISTICS IO ON;entrambi (è così che popoliamo la nostra Table I/Oscheda).
Considerare la seguente vista e funzione su AdventureWorks2012. Questo è solo un tentativo sciocco di restituire una riga casuale dalla tabella dei dettagli, data una riga casuale dalla tabella dell'intestazione, principalmente per assicurarsi che generiamo il maggior numero di I / O possibile, ogni volta.
CREATE VIEW dbo.myview
WITH SCHEMABINDING
AS
SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID()
FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO
CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
RETURN
(
SELECT TOP (1) rowguid FROM dbo.myview
WHERE SalesOrderID = @SalesOrderID ORDER BY n
);
END
GO
Cosa ti dice (e non fa) Management Studio
Prendi la seguente query in SSMS:
SET STATISTICS IO ON;
SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID)
FROM Sales.SalesOrderHeader ORDER BY NEWID();
SET STATISTICS IO OFF;
Quando si stima un piano, si ottiene un piano per la query e un singolo piano per la funzione (non 5, come si potrebbe sperare):

Ovviamente non si ottengono dati I / O, poiché la query non è stata effettivamente eseguita. Ora genera un piano reale. Ottieni le 5 righe che ti aspettavi nella griglia dei risultati, il seguente piano (che non menziona assolutamente l'UDF, tranne che nell'XML puoi trovarlo come parte del testo della query e come parte dell'operatore scalare):

E il seguente STATISTICS IOoutput (che non fa assolutamente menzione Sales.SalesOrderDetail, anche se sappiamo che doveva leggere da quella tabella):
Tabella 'SalesOrderHeader'. Conteggio scansioni 1, letture logiche 57, letture fisiche 0, letture avanti 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0.
Cosa ti dice Plan Explorer
Quando generiamo un piano stimato per la stessa query, conosciamo la stessa cosa di SSMS. Tuttavia mostriamo le cose in un modo leggermente più intuitivo. Ad esempio, il piano stimato per la query esterna mostra come l'output della funzione è combinato con l'output della query ed è immediatamente chiaro - all'interno di un singolo diagramma del piano - che c'è I / O da entrambe le tabelle :

Mostriamo anche il piano della funzione da solo , che includo solo per completezza:

Ora diamo un'occhiata a un piano reale, che è migliaia di volte più utile. Il rovescio della medaglia qui è, ancora una volta, abbiamo solo le informazioni che SQL Server decide di mostrare, quindi possiamo esporre solo i diagrammi del piano grafico che SQL Server ci fornisce. Questa non è una situazione in cui abbiamo deciso di non mostrarti qualcosa di utile; in realtà non ne sappiamo nulla in base al piano XML che ci viene fornito. In questo caso, è proprio come in SSMS, vediamo solo il piano della query esterna ed è come se la funzione non fosse affatto chiamata :

Anche la nostra scheda I / O tabella si basa ancora sull'output diSTATISTICS IO , che ignora anche qualsiasi attività eseguita nella chiamata di funzione:

Tuttavia, riceviamo l'intero stack di chiamate per te. Di tanto in tanto ho sentito gente chiedere: "Pffft, quando avrò mai bisogno dello stack di chiamate?" Possiamo effettivamente scomporre il tempo impiegato, la CPU utilizzata e il numero di letture (e, per i TVF, il numero di righe prodotte) per ogni singola chiamata di funzione :

Sfortunatamente non abbiamo la possibilità di correlare ciò a quale tabella (e) proviene l'I / O (di nuovo, perché SQL Server non ci fornisce tali informazioni) e non è etichettato con il nome UDF (perché viene acquisito come un'istruzione ad hoc, non la chiamata della funzione stessa). Ma ciò che ti permette di vedere, che Management Studio non fa, è ciò che un cane è il tuo UDF. Devi ancora unire alcuni punti, ma ci sono meno punti e sono più vicini.
Informazioni su Profiler
Infine, consiglio vivamente di stare alla larga da Profiler, a meno che non si tratti di impostare una traccia sul lato server che si intende eseguire al di fuori dell'ambito di qualsiasi strumento di interfaccia utente. L'uso di Profiler su un sistema di produzione quasi sicuramente causerà più problemi di quanti ne risolverà mai . Se desideri ottenere queste informazioni, utilizza una traccia sul lato server o eventi estesi e assicurati di filtrare molto saggiamente. Anche senza profiler, una traccia può avere un impatto sul tuo server e il recupero di showplan attraverso eventi estesi non è la cosa più efficiente al mondo .