Kralizek
10-11-2008, 20:34
Salve a tutti. Ho un problema abbastanza rognoso a lavoro e non ho idea di dove sbattere la testa per risolverlo o quanto meno agirarlo.
Il problema riguarda le perfomance di una table-valued function che passa, da 77 ms a 8500 ms con cambi minimi.
Ecco una descrizione sommaria del problema:
La funzione esistente crea una vista sul join di 3 tabelle filtrandola poi per un parametro che è, tra l'altro, chiave esterna verso una quarta tabella. Le tre tabelle sono in legame 1 -> M tra le 2 grosse (diciamo A e B), e la terza (C) è una specie di contenitore di valori enumerati, quindi ci sono due associazioni 1->M da A a C ed un'altra 1->M da B a C.
Il mio compito è cambiare la colonna attraverso cui viene filtrata la tabella risultante dal join utilizzando un'altra chiave esterna (che inizialmente non era neanche segnata come FK).
Il problema è che, per la logica della query, tirarmi fuori il vecchio parametro da una quinta tabella ed usarlo per alcuni calcoli. Questo calcolo non è che la selezione di una colonna filtrata tramite chiave primaria in una tabella da, forse, 100 record. Non posso credere che l'aggiungere questa estrazione aumenti il tempo necessario di 8 secondi dato che, tra l'altro, il valore da utilizzare è lo stesso in tutta la funzione, non va calcolato quindi per ogni record.
Ho provato prima con una funzione inline, e "quel valore" era calcolato 3 volte, una per ogni necessità, affidandomi al caching del dbms. Visti i tempi scandalosi, ho optato per una funzione non inline, ma i tempi, se possibili, sono peggiorati, 10/12 sec, forse dovuto al fatto che si crea una tabella di appoggio e gli si copiano dentro di dati di interesse.
Lavorando di profiler ho scoperto che il query optimizer suggerisce di creare un indice sulla tabella B per migliorare le prestazioni del 75%. Purtroppo questo indice, una volta creato, non sembra incidere particolarmente.
Cosa suggerite? Spero di essere stato chiaro!
Il problema riguarda le perfomance di una table-valued function che passa, da 77 ms a 8500 ms con cambi minimi.
Ecco una descrizione sommaria del problema:
La funzione esistente crea una vista sul join di 3 tabelle filtrandola poi per un parametro che è, tra l'altro, chiave esterna verso una quarta tabella. Le tre tabelle sono in legame 1 -> M tra le 2 grosse (diciamo A e B), e la terza (C) è una specie di contenitore di valori enumerati, quindi ci sono due associazioni 1->M da A a C ed un'altra 1->M da B a C.
Il mio compito è cambiare la colonna attraverso cui viene filtrata la tabella risultante dal join utilizzando un'altra chiave esterna (che inizialmente non era neanche segnata come FK).
Il problema è che, per la logica della query, tirarmi fuori il vecchio parametro da una quinta tabella ed usarlo per alcuni calcoli. Questo calcolo non è che la selezione di una colonna filtrata tramite chiave primaria in una tabella da, forse, 100 record. Non posso credere che l'aggiungere questa estrazione aumenti il tempo necessario di 8 secondi dato che, tra l'altro, il valore da utilizzare è lo stesso in tutta la funzione, non va calcolato quindi per ogni record.
Ho provato prima con una funzione inline, e "quel valore" era calcolato 3 volte, una per ogni necessità, affidandomi al caching del dbms. Visti i tempi scandalosi, ho optato per una funzione non inline, ma i tempi, se possibili, sono peggiorati, 10/12 sec, forse dovuto al fatto che si crea una tabella di appoggio e gli si copiano dentro di dati di interesse.
Lavorando di profiler ho scoperto che il query optimizer suggerisce di creare un indice sulla tabella B per migliorare le prestazioni del 75%. Purtroppo questo indice, una volta creato, non sembra incidere particolarmente.
Cosa suggerite? Spero di essere stato chiaro!