2015-10-01 26 views
5

Ciao Sto usando psycopg2 per l'accesso postgres.Cursori con postgres, dove sono memorizzati i dati e quante chiamate al DB

Sto cercando di capire dove "cursore" memorizza le righe restituite. Lo memorizza nel database come una tabella temporanea o si trova sul lato client?

Il cursore (quando si specifica il recupero di più righe) esegue una query sul database una volta alla volta o colpisce il database una volta, ottiene il primo set di risultati e quindi quando si esegue l'iterazione sui valori restituiti, ottiene il successivo set (buffering).

Ho letto più articoli sul cursore ma niente di veramente dà il funzionamento interno ...

Grazie.

+0

Invia il tuo codice di prova –

risposta

3

Il set di dati per un cursore viene preparato dal server al momento dell'esecuzione del primo FETCH. L'applicazione client riceve solo i risultati delle successive istruzioni FETCH.

Se il server non può utilizzare gli indici per mantenere un cursore, viene creato il set di dati temporaneo. È possibile eseguire questo semplice test:

create table test(i int, v text); 
insert into test 
select i, i::text 
from generate_series(1, 5000000) i; 

eseguire le istruzioni in questo script ad uno ad uno:

begin; 

declare cur cursor 
for select * from test 
order by random();    -- 17 ms 

fetch next cur;    -- 37294 ms (*) 

fetch next cur;    -- 0 ms 
fetch prior cur;    -- 0 ms 
fetch absolute 1000000 cur; -- 181 ms 
fetch relative 1000000 cur; -- 163 ms 
fetch first cur;    -- 0 ms 
fetch last cur;    -- 0 ms 

rollback; 

Prima fetch (*) esegue all'incirca intorno allo stesso tempo come la creazione di una tabella temporanea simile :

create temp table temp_test as 
select * from test 
order by random();    -- 51684 ms 

Alcuni driver possono avere la propria implementazione del cursore sul lato client. Questo dovrebbe essere esplicitamente descritto nella documentazione del driver.

+0

PostgreSQL non sempre materializzerà i dati in quel modo. A volte può essere recuperato solo quando necessario. Dipende dal piano di query esatto. Francamente sono sorpreso che sembra materializzarlo in questo caso. Inoltre, si noti che questo è con un cursore sul lato server. I cursori di 'psycopg2' sono mappati ai cursori lato server, quindi il comportamento corrisponderà piuttosto bene, ma questo non è necessariamente vero per gli altri driver. Ad esempio, PgJDBC riceve l'intero set di risultati nella memoria locale per impostazione predefinita. –

+0

@Craig, questo è solo un esempio. Ho scelto il caso peggiore per illustrare meglio il meccanismo dei cursori di utilizzo. Grazie per il consiglio. – klin