Mysql
 sql >> Database >  >> RDS >> Mysql

Evitare le query annidate

Dipende davvero, ho avuto situazioni in cui ho migliorato alcune query utilizzando le sottoquery.

I fattori di cui sono consapevole sono:

  • se la sottoquery utilizza o meno i campi della query esterna per il confronto (correlato oppure no)
  • se la relazione tra la query esterna e la sottoquery è coperta da indici
  • se non ci sono indici utilizzabili sui join e la sottoquery non è correlata e restituisce un piccolo risultato potrebbe essere più veloce utilizzarlo
  • Mi sono anche imbattuto in situazioni in cui trasformare una query che utilizza order by in una query che non la utilizza e poi trasformarla in una semplice sottoquery e sort che migliora le prestazioni in mysql

Ad ogni modo, è sempre bene testare diverse varianti (con SQL_NO_CACHE per favore) e trasformare le query correlate in join è una buona pratica.

Andrei anche così lontano da definirla una pratica molto utile.

Potrebbe essere possibile che se le query correlate sono le prime che ti vengono in mente che non stai pensando principalmente in termini di operazioni sugli insiemi, ma principalmente in termini di operazioni procedurali e quando si ha a che fare con database relazionali è molto utile adottare pienamente l'insieme prospettiva sul modello di dati e trasformazioni su di esso.

EDIT:Procedurale vs Relazionale
Pensare in termini di operazioni sugli insiemi rispetto a procedurali si riduce all'equivalenza in alcune espressioni di algebra di insiemi, ad esempio la selezione su un'unione è equivalente all'unione di selezioni. Non c'è differenza tra i due.
Ma quando si confrontano le due procedure, come applicare i criteri di selezione a ogni elemento di un'unione con fare un'unione e quindi applicare la selezione, le due procedure sono nettamente diverse, il che potrebbe hanno proprietà molto diverse (ad esempio utilizzo di CPU, I/O, memoria).

L'idea alla base dei database relazionali è che non si tenta di descrivere come ottenere il risultato (procedura), ma solo ciò che si desidera, e che il sistema di gestione del database deciderà il percorso migliore (procedura) per soddisfare la richiesta. Questo è il motivo per cui SQL è chiamato linguaggio di quarta generazione (4GL) .

Uno dei trucchi che ti aiutano a farlo è ricordare a te stesso che le tuple non hanno un ordine intrinseco (gli elementi del set non sono ordinati). Un altro è rendersi conto che l'algebra relazionale è abbastanza completa e consente la traduzione delle richieste (requisiti) direttamente in SQL (se la semantica di il tuo modello rappresenta bene lo spazio del problema, o in altre parole se il significato allegato al nome delle tue tabelle e relazioni è fatto bene, o in altre parole se il tuo database è progettato bene).

Pertanto, non devi pensare come, solo cosa.

Nel tuo caso, era solo una preferenza rispetto alle query correlate, quindi potrebbe essere che non ti sto dicendo nulla di nuovo, ma hai sottolineato questo punto, da cui il commento.

Penso che se fossi completamente a tuo agio con tutte le regole che trasformano le query da un modulo all'altro (regole come la distributività) che non preferiresti subquery correlate (che vedresti tutte le forme uguali).

(Nota:sopra discute il background teorico, importante per la progettazione del database; praticamente i concetti di cui sopra deviano:non tutte le riscritture equivalenti di una query vengono necessariamente eseguite poiché le chiavi primarie veloci e raggruppate fanno sì che le tabelle ereditino l'ordine sul disco, ecc... ma queste le deviazioni sono solo deviazioni; il fatto che non tutte le query equivalenti vengano eseguite così velocemente è un'imperfezione del DBMS effettivo e non dei concetti alla base)