Utilizzando MSSQL 2005UDF vs prestazioni di SQL diretto
stavo giocando in giro oggi con uno scalare UDF in un comunicato in cui per vedere alcuni dei costi associati di effettuare la chiamata e IO differenze ecc
I' m iniziando con 2 tavoli base. Cliente che ha 1 milione di righe. e gli acquisti che ha 100.000. Entrambi hanno una colonna di identità automatica come chiave primaria. Nessun altro indice definito.
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
SET STATISTICS IO ON
SELECT * FROM Customer C
INNER JOIN Purchases P on C.[IDENTITY] = P.CustomerID
WHERE P.Amount > 1000
SET STATISTICS IO OFF
Questo restituisce le statistiche IO di
Table 'Customer'. Scan count 0, logical reads 3295, physical reads 1, read-ahead reads 32, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Purchases'. Scan count 1, logical reads 373, physical reads 1, read-ahead reads 370, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Quindi, solo per vedere l'impatto di un'UDF scalare Ho poi appena spostato il P.Amount> 1000 ad un'UDF. La funzione è la seguente:
CREATE FUNCTION [dbo].[HighValuePurchase]
(
@value int
)
RETURNS bit
AS
BEGIN
DECLARE @highValue bit
SET @highValue = '0'
IF @value > 1000
BEGIN
SET @highValue = '1'
END
RETURN @highValue
END
Così ho poi corse la seguente query:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
SET STATISTICS IO ON
SELECT * FROM Customer C
INNER JOIN Purchases P on C.[IDENTITY] = P.CustomerID
WHERE dbo.HighValuePurchase(P.Amount) = '1'
SET STATISTICS IO OFF
mi aspettavo questo per funzionare peggio. Questa query ha restituito le seguenti statistiche IO:
Table 'Purchases'. Scan count 1, logical reads 373, physical reads 1, read-ahead reads 370, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customer'. Scan count 1, logical reads 35, physical reads 3, read-ahead reads 472, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Questo anche restituito più veloce del> 1000 query. Mentre venivano restituite le stesse righe, l'ordinamento di quella che chiamava l'UDF veniva automaticamente ordinato da C. [IDENTITY] dove l'altra query appariva non ordinata. Ciò è probabilmente dovuto al modo in cui le mietitrebbie sono state eseguite nei piani di esecuzione. Il profilo dei piani è sotto.
Il piano di esecuzione per la non UDF mostra una scansione indice cluster per acquisti e un indice cluster ricerca per clienti combinati a un join nidificato.
Il piano di esecuzione per la versione UDF mostra una scansione dell'indice cluster per gli acquisti, quindi un filtro, quindi un ordinamento. C'è una scansione indice raggruppata sul cliente. Quindi i risultati vengono combinati in Unisci join.
Sono sicuro che questo ha a che fare con la mancanza di indici, ecc., Ma non sono sicuro del perché questi risultati siano così come sono. Ho sperimentato la corsa di UDF dolorosamente lenta e tutti dicono che usarli di solito è una cattiva idea, motivo per cui ho lanciato questo test insieme. Al momento non posso spiegare perché la versione UDF sembra essere molto meglio.
Abbiamo trovato alcune informazioni relative a questo: http://sqlinthewild.co.za/index.php/2009/04/29/functions-io-statistics-and-the-execution-plan/ I still can ' t ottenere le statistiche IO "reali" per la query sopra, ma questo almeno aiuta a spiegarlo. – Equixor
Non sembra che tu abbia una risposta su questo forum. Potrebbe voler pubblicare su un sito più sql specifico. vale a dire. http://www.sqlservercentral.com/Forums/ –
perché mai dovresti nominare una colonna IDENTITY ??? perché non nominarlo CustomerID in entrambe le tabelle ??? nominare cose come questa uccide la prossima povera persona che dovrà lavorare su questo sistema dopo di te. –