Domanda

Sto notando un degrado esponenziale delle prestazioni nei tempi di esecuzione delle query MySQL quando le query includono chiamate a UDF nelle clausole SELECT o WHERE. Le UDF in questione interrogano le tabelle locali per restituire valori scalari, quindi non solo eseguono espressioni aritmetiche, ma fungono da sottoquery correlate. Ho risolto il problema delle prestazioni semplicemente rimuovendo l'UDF e riscrivendolo con sottoquery correlate, join più complessi, ecc.

Suppongo che se avessi avuto esperienza con MySQL, accetterei semplicemente questo come realtà, regolerei il mio uso degli UDF e andrei avanti. Ma prima di lavorare con MySQL ho lavorato per 5+ anni su SQL Server. Ho creato un sistema di fatturazione che ha elaborato set di dati molto più grandi e ha fatto affidamento su molto pesantemente sia su funzioni scalari che su valori di tabella definiti dall'utente. Quelle UDF hanno anche eseguito query (cioè non solo operazioni aritmetiche). Non ho riscontrato questo tipo di penalità per le prestazioni durante l'utilizzo delle funzioni definite dall'utente su SQL Server.

Quello che mi chiedo è se c'è qualcuno qui che conosca gli interni di SQL Server e MySQL abbastanza bene da confermare o spiegare la mia attuale teoria sulla causa di questa differenza di prestazioni in UDF sui due sistemi. La mia teoria è che l'ottimizzatore di SQL Server valuta l'UDF in modo diverso da quello di MySQL. Forse è perché i motori da tavolo sono disaccoppiati in MySQL? O forse l'uso di UDF su SQL Server è più diffuso e l'ottimizzatore del motore MySQL non si è ancora evoluto finora? Quello che sto pensando è che forse i trattamenti di ottimizzazione di SQL Server includevano UDF come parte della query circostante (quando possibile) e quindi l'ottimizza insieme al resto della query? Forse qui sono fuori strada, ma non ho mai visto questo tipo di prestazioni per l'utilizzo di UDF su SQL Server.

Ogni luce che gli altri possano far luce su questo problema sarà apprezzata.

È stato utile?

Soluzione

Le UDF hanno limiti e problemi noti. Vedi: Gli UDF sono dannosi per le prestazioni di SQL Server?

Ci sono molti articoli su questo argomento. Speriamo che questo sia un accesso non abbonato: Attenzione alle operazioni riga per riga in UDF Abbigliamento

Altri suggerimenti

So che questa è una vecchia domanda, ma viene prima nella ricerca di Google "Prestazioni UDF di MySQL" e non ha ancora una risposta adeguata: un collegamento nella risposta accettata è interrotto, l'altro non sembra parlare delle specifiche degli UDF di MySQL.

Per prima cosa, assicuriamoci di parlare degli UDF MySQL reali. In MySQL, esiste una distinzione tra una "funzione memorizzata" e un UDF. Una funzione memorizzata viene eseguita utilizzando l'interprete della funzione / procedura memorizzata interna. Un UDF è scritto in C ++ ed è compilato in una libreria condivisa che viene caricata dal server MySQL nella memoria e quando viene chiamata, viene eseguita come codice macchina sulla CPU. Pertanto, le prestazioni UDF sono spesso ordini di grandezza migliori di quelle delle funzioni memorizzate.

Quindi, prima di tutto, assicurati di parlare dell'UDF reale, e questa non è una funzione memorizzata.

In secondo luogo, le prestazioni UDF di MySQL dipendono dalla natura dell'algoritmo che sta eseguendo e dalla qualità della sua implementazione. Ad esempio, se il tuo UDF sta testando tutte le possibili terzine di caratteri di una stringa lunga 1000 byte, esaminerà 1 miliardo di combinazioni e richiederà circa alcuni secondi per riga. Quindi, se la rimozione degli UDF rende il tuo codice molto più veloce, il prossimo passo è il debug dell'UDF stesso per assicurarti che sia scritto in modo ottimale - o forse alla domanda a cui l'UDF sta cercando di rispondere non è possibile rispondere rapidamente.

Detto questo, un UDF ben scritto che sta rispondendo a una domanda relativamente semplice è solitamente velocissimo rispetto all'I / O necessario per fornire i dati da analizzare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top