E niente sulle funzioni. Perché le informazioni sulla funzione mancano nel piano attuale?
Questo è di progettazione, per motivi di prestazioni.
Le funzioni che contengono BEGIN
e END
nella definizione creano un nuovo frame stack T-SQL per ogni riga di input. Detto in altro modo, il corpo della funzione viene eseguito separatamente per ogni riga di input . Questo singolo fatto spiega la maggior parte dei problemi di prestazioni associati alle funzioni scalare e multiistruzione di T-SQL (si noti che le funzioni con valori di tabella in linea non usano la BEGIN...END
sintassi).
Nel contesto della tua domanda, ciò comporterebbe un SHOWPLAN
output completo per ogni riga. L'output del piano XML è abbastanza dettagliato e costoso da produrre, quindi produrre un output completo per ogni riga sarebbe una cattiva idea in termini generali.
Esempio
Considera la seguente funzione scalare T-SQL, creata nel database di esempio AdventureWorks , che restituisce il nome di un prodotto dato il suo ID:
CREATE FUNCTION dbo.DumbNameLookup
(
@ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
RETURN
(
SELECT
p.Name
FROM Production.Product AS p
WHERE
p.ProductID = @ProductID
);
END;
Piano di pre-esecuzione
Un piano di pre-esecuzione (piano stimato in SSMS) mostra le informazioni sul piano per l'istruzione parent e le chiamate di funzione nidificate:
-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;
Uscita SSMS:
Lo stesso XML visualizzato in SQL Sentry Plan Explorer mostra più chiaramente la natura nidificata delle chiamate:
Uscita post-esecuzione
SSMS mostra i dettagli solo per la query principale quando viene richiesto l'output del piano di post-esecuzione:
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
L'impatto sulle prestazioni di fare diversamente può essere mostrato utilizzando la classe di eventi Showplan XML Statistics Profile in SQL Server Profiler, utilizzando una query che chiama la funzione più volte (una volta per riga di input):
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
Uscita del profiler:
Esistono cinque piani di post-esecuzione separati per le esecuzioni delle funzioni e uno per la query principale. I cinque piani di funzione si presentano così nel riquadro inferiore del profiler:
Il piano di query principale è:
L'esecuzione della query senza la TOP (5)
clausola comporta un piano di esecuzione completo per ciascuna delle 504 righe nella tabella Prodotto. Probabilmente puoi vedere come ciò sfuggirebbe rapidamente ai tavoli più grandi.
La situazione per i trigger è invertita. Questi non mostrano alcuna informazione sul piano di pre-esecuzione, ma includono un piano di post-esecuzione. Ciò riflette la natura basata su set di trigger; ognuno viene attivato una volta per tutte le righe interessate, anziché una volta per riga.