Join multipli o semplici chiamate al database leggibili

4

Curioso di come si sentono gli altri sviluppatori. Sono imbattuto in alcuni giusti sql piuttosto cattivi, come tutti noi ne sono sicuro. Preferirei effettuare più chiamate al database per motivi di leggibilità e semplicità piuttosto che avere una grande istruzione SQL da mantenere; circa 3 - 4 join. Per l'argomento delle prestazioni, rinuncerò a una piccola prestazione per la leggibilità.

Ad esempio: effettua la prima chiamata, filtra i dati, quindi esegui una query sulla seconda tabella e così via

Qual è la tua preferenza?

    
posta Scott Radcliff 29.08.2011 - 19:32
fonte

4 risposte

9

Spesso vedo codice facepalm che recupera un set di risultati e scorre su di esso, eseguendo un'altra query SQL su una tabella di riferimento per ogni riga. Perché? "Perché i join sono negativi."

Ad esempio (pseudocodice):

SELECT * FROM Users;
for each user row {
    SELECT * FROM Orders WHERE Orders.user = $user;
    for each order row {
         SELECT * FROM LineItems WHERE LineItems.order = $order;
         for each lineitem row {
             SELECT * FROM Products WHERE Products.id = $lineitem;
         }
    }
}

Se si progettano bene tabelle e indici, i join sono un modo efficace per filtrare i dati all'interno dell'RDBMS e restituire un piccolo set di risultati. Sicuramente più efficiente del lavoro equivalente nel codice dell'applicazione.

    
risposta data 29.08.2011 - 19:48
fonte
1

Nella mia esperienza, query più ampie danno a SQL Server maggiori possibilità di sbagliare. L'utilizzo di query più piccole può aiutare SQL Server a utilizzare un buon piano di query. Ad esempio, nel proprio ambiente di sviluppo, SQL Server potrebbe eseguire una query enorme esattamente nell'ordine in cui è stata scritta. Successivamente, quando il codice passa alla produzione, improvvisamente i dati sono molto diversi. SQL Server potrebbe assumere un'ipotesi errata e scegliere di avviare la query nel mezzo, e all'improvviso si finirà con unioni pazzesche che creano un miliardo di record temporanei da spoolare in tempdb.

Le prestazioni di query complicate contro enormi database variano. A volte, avere una query complicata funziona meglio, perché elabora i dati solo una volta. A volte, separare i passaggi è più veloce e più leggibile, perché è possibile garantire che i risultati della prima query limitino i dati a un piccolo insieme di righe prima di eseguire il resto dei passaggi.

Cerco di utilizzare query separate per passaggi logici separati. Documenterò ogni passaggio con i commenti in modo da poter ricordare più facilmente ciò che stava cercando di realizzare. Ad esempio:

  1. Fai qualche pre-elaborazione per capire cosa vuole l'utente
  2. Raccogli i dati, filtrando alla selezione dell'utente
  3. Inserisci dati basati sulla data da una tabella dei prezzi
  4. Rilascia alcuni record che non sono rilevanti a causa di alcune rare condizioni
  5. Compila alcuni campi a fini di reporting
  6. Restituisce i risultati

Se ti unisci a più livelli di sottoquery, come nell'esempio di Bill, suddividere le subquery in passaggi separati può migliorare le prestazioni.

Nota inoltre che il tuo piano potrebbe sostenere più I / O mentre crei, popoli, indicizzi e selezioni da tabelle temporanee.

E infine, se non è rotto-- non aggiustarlo!

    
risposta data 29.08.2011 - 20:07
fonte
0

Se sono solo 3-4 semplici join, probabilmente non mi preoccuperei troppo; questo non è affatto un database abbastanza grande. Ho visto query SQL che si avvicinano a quel numero di dozzine di join, con sottogruppi di sottogruppi - ora è quando inizia a diventare ingombrante! Di solito c'è una buona ragione per quasi ognuno di loro quando presi isolatamente, ma ad un certo punto è passata dall'essere ragionevole ad irragionevole alla pura follia con "solo un'altra" condizione o campo necessario. A un certo punto è necessario prendere in considerazione il refactoring della query (quando si trova che per ottenere prestazioni ragionevoli, l'ordine di join diventa significativo o sono necessari suggerimenti di query, che di solito è un grande segnale di avvertimento) e lo suddivide in più query più piccole, ma a meno che quei join non siano veramente orrendi, non credo che tu sia ancora a quel punto.

La singola regola più importante è in realtà provarci . Guarda il piano di esecuzione. Il server di database rende l'uso più efficiente possibile degli indici, oppure puoi aggiungere un indice filtrato su alcune tabelle che ti aiuterà a migliorare le prestazioni senza farti male troppo in altri posti? Riscrivi la query e confronta i tempi di esecuzione, i requisiti di I / O e il piano di esecuzione. In realtà aiuta? Inoltre, tieni presente che in qualsiasi query non banale, riscrivendola (anche se sembra "semplice"), corri il rischio di introdurre un bug.

    
risposta data 30.08.2011 - 10:59
fonte
0

Suggerimento: le query SQL possono essere commentate per aiutare a capire come funzionano. Lo stesso suggerimento vale per le espressioni regolari.

Se pensi che più query siano migliori di una grande (ben scritta), dovresti provarla con un server RDMS che non è in esecuzione sulla stessa macchina del tuo server delle applicazioni.

    
risposta data 31.08.2011 - 10:32
fonte

Leggi altre domande sui tag