Eu tenho uma mesa data
:
- com aproximadamente 400 milhões de linhas
- com
data.id
como int4 , não null e definido como chave primária - é um servidor AWS RDS, com ~ 128G de RAM
- não há linha com id > 1e9
Esta consulta:
select count(*) from data where id > 1e9;
que retorna 0, leva consistentemente cerca de 25s para ser executado. Costuma levar mais de 2 minutos (posso ter corrido analyze data
durante minhas investigações e o tempo caiu para 25s).
Em outro servidor, um aws aurora Postgres com exatamente a mesma tabela, leva cerca de 3m30s.
De qualquer forma, a mesma consulta leva alguns ms em um banco de dados MySQL, como deveria. Sou muito novo no Postgres, então provavelmente estou perdendo algo óbvio.
explicar analisar selecionar contagem (*) dos dados onde id > 1e9;
QUERY PLAN
Finalize Aggregate (cost=11944927.24..11944927.25 rows=1 width=8) (actual time=23986.851..23988.183 rows=1 loops=1)
-> Gather (cost=11944927.03..11944927.24 rows=2 width=8) (actual time=23986.779..23988.177 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=11943927.03..11943927.04 rows=1 width=8) (actual time=23984.078..23984.079 rows=1 loops=3)
-> Parallel Index Only Scan using data_pkey on data (cost=0.57..11804489.05 rows=55775191 width=0) (actual time=23984.074..23984.075 rows=0 loops=3)
Filter: ((id)::numeric > '1000000000'::numeric)
Rows Removed by Filter: 133840000
Heap Fetches: 100863313
Planning Time: 0.078 ms
Execution Time: 23988.219 ms
O que estou fazendo de errado?
Presumo que você tenha um índice em
id
. Se não, você precisa de um.Seu problema é o
1e9
. Se você escrever uma constante numérica com a notação científica, ela será considerada do tiponumeric
:Portanto, o PostgreSQL precisa converter
id
para o tiponumeric
para realizar a comparação (no(id)::numeric
seu plano de execução) e não pode usar o índice.Usar uma constante do tipo
integer
deve acelerar o processamento: