Prestazioni di Inline-TVF vs. Views


9

Ho un database in cui sto usando TVF in linea (funzioni valore tabella) invece di visualizzazioni. Ad esempio, potrei avere due tabelle chiamate [modello di automobile] e [produttore di automobili] che sto unendo all'interno del TVF [fnCarBrands].

Questi TVF vengono quindi chiamati da altri TVF per eseguire ulteriori elaborazioni e rapporti. Quindi potrei prendere la mia funzione [fnCarBrands] e unirmi alla tabella [Anno acquisto] per formare una funzione [fnCarBrandHistory]. E così via per diversi livelli di TVF.

Probabilmente potrei ottenere la stessa funzionalità usando le viste, dal momento che i miei TVF in linea sono in realtà solo unioni di tavoli e altri TVF.

In che modo le prestazioni dei TVF in linea scritti in questo modo si confrontano con le visualizzazioni?


Molto probabilmente vedresti gli stessi piani di esecuzione e le stesse prestazioni.
AK,

è quello che pensavo, ma mi è stato detto che il TVF si comporta come una parentesi in algebra: costringe il motore DB a completare la query prima di ottimizzare. L'uso delle viste, mi viene detto, consente all'ottimizzatore di ottimizzare l'intera query come unità.
FistOfFury

Una specie di nota a margine ma hai idea del perché i TVF sono stati usati al posto delle viste? Semplicemente approccio code-monkey vs data-monkey al problema?
Mark Storey-Smith,

@ MarkStorey-Smith sì, il motivo è come dici tu, approccio code-monkey vs data-monkey.
FistOfFury

Risposte:


12

Query Optimizer considera una funzione con valori di tabella incorporata esattamente come una vista:

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

Una funzione con valori di tabella con più istruzioni viene eseguita più come una stored procedure. In genere devono essere eseguiti più volte, anziché essere piegati nella query principale:

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;

1
@Andomar la mia comprensione è che i TVF a più istruzioni sono eseguiti come una scatola nera, il motore non sa cosa c'è dentro e non può ottimizzare la query. Hai articoli a cui puoi fare riferimento per affermare che visualizzazioni e TVF in linea sono equivalenti?
FistOfFury

4

Dovrai creare viste simili alle funzioni e interrogare ognuna guardando il piano di esecuzione per vedere cosa sta succedendo con ciascuna.


Esattamente. Benchmarking, vedere di persona: questo è l'unico modo affidabile per imparare.
AK,

@mrdenny Non c'è modo di prevedere come l'ottimizzatore tratterà ogni tipo di query? Sicuramente ci sono alcune regole che segue.
FistOfFury

2
@FistOfFury Sì, ci sono regole, tra migliaia e migliaia, complimentate con centinaia di anni di sviluppo di codice euristico. Ecco perché dovrai testare o chiedere a Microsoft il codice sorgente dell'ottimizzatore.
Mark Storey-Smith,

Se desideri comprendere meglio come il motore di database determina cosa fare, devi leggere su SQL Server Internals, amazon.com/s/…
HLGEM

3

Naturalmente la creazione di viste che chiamano altre viste è anche un killer delle prestazioni. Non seguire questa strada. Scrivi le query di cui hai bisogno e non utilizzare TVF o visualizzazioni se desideri prestazioni. È la stratificazione che sta creando il problema, questa è quasi sempre una brutta cosa da fare quando si esegue una query su un database e si può rapidamente finire col colpire il limite del numero di tabelle a cui è possibile fare riferimento, soprattutto perché spesso si finisce per fare riferimento al stesse tabelle in diversi livelli. Inoltre, sebbene ciò sembri più facile da mantenere, non lo è. Prova a eseguire il debug o ad aggiungere una colonna a causa di un nuovo requisito quando il livello che devi correggere è in fondo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.