Come dedurre il risultato di una query?

3

Per capire che cosa fa una query, ho sempre pensato che quanto segue fosse la procedura sulla valutazione di una query:

  1. Forma la tabella come specificato nella clausola FROM.

  2. Scegli le righe da quella tabella come specificato nella clausola WHERE.

  3. Mostra le colonne delle righe risultanti, come specificato nella clausola SELECT.

Ma il problema è; tutt'intorno, vedo che SQL è un linguaggio dichiarativo . Cioè, non c'è nessuna garanzia come verrà eseguita una particolare query. Detto questo, la mia domanda è:

Il ragionamento sul risultato di una query è nel modo in cui io sbaglio? In tal caso, come dovrei ragionare sul risultato di una query? In altre parole, se non sono in grado di ragionare passo dopo passo, come dovrei prevedere quale sarà il risultato di una determinata query?

Il fatto è che, sebbene questo non sia un grosso problema nelle query banali, dato che le query diventano più complesse, ad esempio incorporando varie sottoquery correlate, non riesco a vedere come dovrei capire cosa fa una query, senza pensando alla query in un'esecuzione passo-passo. Quindi, vorrei imparare come ragionare sulle query SQL.

    
posta Utku 29.03.2015 - 14:58
fonte

2 risposte

8

Il ragionamento sul significato di una query (cioè i risultati che dovrebbe produrre) usando l'approccio procedurale ingenuo che descrivi è perfettamente corretto. Come dici tu, con query complesse spesso è l'unico modo semplice per capire cosa sta succedendo.

Il problema sarebbe se si usasse questo ragionamento per dedurre proprietà sulla query esecuzione (come la complessità temporale o l'utilizzo della memoria). Non è saggio perché il vero database utilizza probabilmente indici e tabelle temporanee e pianificatori di query contenenti tutti i tipi di ottimizzazioni della magia nera che non si devono e non si devono sapere. Finché non assumi mai ipotesi come "Le subquery annidate utilizzano molta memoria perché costruiscono tabelle temporanee" senza alcuna prova concreta, dovresti stare bene.

Se hai qualche background in matematica, potrebbe essere utile pensare a dichiarazioni dichiarative come le query SQL come definizioni di insiemi matematici. Ad esempio, il risultato di questa query:

SELECT id, name FROM table WHERE id > 10

è probabilmente equivalente a un set come questo:

S = { {id, name} | id > 10 ∧ ∃row (row ∈ table) ∧ row(0) = id ∧ row(1) = name }

Dato che la notazione del set-builder non è normalmente intesa come pseudocodice per gli algoritmi di costruzione di set, questa formazione pone una certa distanza mentale tra la definizione di query / set e l'algoritmo ingenuo che capita di implicare.

    
risposta data 29.03.2015 - 22:39
fonte
1

In effetti, sei in grado di determinare con precisione che cosa restituirà una query utilizzando il ragionamento logico come descritto.

Ciò che SQL non garantisce è in che modo il motore troverà questo risultato. Dà lo stesso risultato come se usasse i passi logici che descrivi, ma in che modo in realtà trova il risultato dipende da una serie di fattori e dettagli di implementazione.

Ad esempio, quando pronunci "Scegli le righe da quella tabella ..." il motore potrebbe non avere realmente bisogno di cercare una tabella, se esiste un indice che include tutte le colonne come per. Ovviamente questo significa che il motore deve prima esaminare le colonne per determinare quali tabelle o indici devono essere utilizzati. Quindi il motore non seguirà effettivamente i passaggi che descrivi, ma il risultato sarà lo stesso.

Se si assumono sottoquery correlate, il risultato sarà come se la sottoquery correlata verrà eseguita una volta per riga nella query principale, ma in realtà Query Optimizer potrebbe trasformare la query in un join che è molto più veloce da eseguire.

    
risposta data 30.03.2015 - 22:59
fonte

Leggi altre domande sui tag