I dettagli dipendono dall'implementazione ma generalmente parlando, i risultati sono bufferizzati. L'esecuzione di una query su un database restituirà un set di risultati. Se è sufficientemente piccolo, tutti i risultati possono essere restituiti con la chiamata iniziale o alcuni potrebbero esserlo e vengono restituiti più risultati durante l'iterazione sull'oggetto risultato.
Pensa alla sequenza in questo modo:
- Apri una connessione al database;
- C'è forse una seconda chiamata per selezionare un database o potrebbe essere eseguita come parte di (1);
- Quel passaggio di autenticazione e connessione è (almeno) un round trip al server (ignorando le connessioni persistenti);
- Esegui una query sul client;
- Quella query viene inviata al server;
- Il server deve determinare come eseguire la query;
- Se il server ha precedentemente eseguito la query, il piano di esecuzione potrebbe essere ancora nella cache delle query. In caso contrario, è necessario creare un nuovo piano;
- Il server esegue la query come indicato e restituisce un risultato al client;
- Quel risultato conterrà del buffer di righe che dipende dall'implementazione. Potrebbero essere 100 righe o più o meno. Vengono restituite tutte le colonne per ogni riga;
- Man mano che recuperi più righe, alla fine il client chiederà al server più righe. Questo può accadere quando il client si esaurisce o può essere fatto preventivamente. Anche questo dipende dall'implementazione.
L'idea di tutto questo è di ridurre al minimo i viaggi di andata e ritorno al server senza restituire troppo dati non necessari, motivo per cui se chiedi un milione di righe non le riavrai tutte in una volta.
Le clausole LIMIT, o di fatto qualsiasi clausola, modificheranno il set di risultati.
Infine, (7) è importante perché SELECT * FROM table WHERE a = 'foo'
e SELECT * FROM table WHERE a = 'bar'
sono due query diverse per quanto riguarda l'ottimizzatore di database, quindi è necessario determinare un piano di esecuzione per ciascuna separatamente. Ma una query parametrizzata (SELECT * FROM table WHERE a = :param
) con parametri diversi è una query e deve essere pianificata solo una volta (almeno fino a quando non esce dalla cache delle query).