L'ensemble de données pour un curseur est préparé par le serveur au moment de l'exécution du premier FETCH. L'application cliente ne reçoit que les résultats des instructions FETCH suivantes.
Si le serveur ne peut pas utiliser d'index pour maintenir un curseur, l'ensemble de données temporaire est créé. Vous pouvez effectuer ce test simple :
create table test(i int, v text);
insert into test
select i, i::text
from generate_series(1, 5000000) i;
Exécutez les instructions de ce script une par une :
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;
First FETCH (*) s'exécute à peu près au même moment que la création d'une table temporaire similaire :
create temp table temp_test as
select * from test
order by random(); -- 51684 ms
Certains pilotes peuvent avoir leur propre implémentation du curseur côté client. Cela devrait être décrit explicitement dans la documentation du pilote.