db=> explain analyze with data as (select a, b, c from D where e='something') select * from Data;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on D (cost=0.00..3060987.06 rows=1955179 width=42) (actual time=0.022..81146.222 rows=2027407 loops=1)
Filter: ((e)::text = 'something'::text)
Rows Removed by Filter: 9757878
Planning Time: 0.083 ms
Execution Time: 89924.754 ms
(5 rows)
db=> explain analyze select * from (select a, b, c from D where e='something') x;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on documentsubjecthistory (cost=0.00..3060987.06 rows=1955179 width=42) (actual time=0.025..81148.606 rows=2027407 loops=1)
Filter: ((subjectentitycodesystem)::text = '2.16.840.1.113883.6.69'::text)
Rows Removed by Filter: 9757878
Planning Time: 0.105 ms
Execution Time: 89925.772 ms
(5 rows)
No entanto, quando realmente executo o primeiro com o with Data (...) select * from Data
CTE, os resultados só aparecem depois desses 89 segundos, enquanto quando executo o select * from (...) x
, obtenho a página inicial rapidamente.
Eu tenho \set FETCH_COUNT 1000
em .psqlrc
O psql anterior à versão 17 ignorará
FETCH_COUNT
consultas que não começam com a palavra-chaveselect
(o documento da versão 16 diz: os resultados das consultas SELECT são buscados e exibidos em grupos com essa quantidade de linhas , e esse SELECT deve ser interpretado literalmente).Nesta questão, a primeira declaração começa com
with
e a segunda comselect
, então o psql v16 ou mais antigo envia a primeira consulta sem modificações e processa todos os seus resultados em uma etapa. O primeiro resultado só fica disponível quando todo o conjunto de resultados foi recuperado na memória. Por outro lado, a segunda consulta é transformada em:Cada bloco de resultados fica disponível imediatamente após cada
FETCH
iteração.A partir do psql v17, a implementação não usa mais um cursor ; ela honra
FETCH_COUNT
usando o novo modo chunked rows , que funciona com todas as consultas. Então, presumivelmente, você veria ambas as consultas entregando os primeiros resultados rapidamente com um psql mais novo.O PostgreSQL v17 foi lançado há apenas dois dias, mas esse recurso não precisa de um servidor atualizado, apenas do cliente mais novo.