PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como fornecer a um cliente de API 1.000.000 de resultados de banco de dados?


A tabela tem uma chave primária. Faça uso dele.

Em vez de LIMIT e OFFSET , faça sua paginação com um filtro na chave primária. Você insinuou isso com seu comentário:

Paginação usando números aleatórios (Adicione "GREATER THAN ORDER BY" a cada consulta)

mas não há nada aleatório sobre como você deve fazer isso.
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2

Permita que o cliente especifique ambos os parâmetros, o último ID que viu e o número de registros a serem buscados. Sua API terá que ter um marcador de posição, um parâmetro extra ou uma chamada alternativa para "buscar o primeiro n IDs" onde omite o WHERE cláusula da consulta, mas isso é trivial.

Essa abordagem usará uma varredura de índice bastante eficiente para colocar os registros em ordem, geralmente evitando uma classificação ou a necessidade de iterar por todos os registros ignorados. O cliente pode decidir quantas linhas deseja de uma só vez.

Essa abordagem difere do LIMIT e OFFSET abordagem de uma maneira fundamental:modificação simultânea. Se você INSERT na tabela com uma tecla inferior do que uma chave que algum cliente já viu, essa abordagem não alterará seus resultados, enquanto o OFFSET abordagem irá repetir uma linha. Da mesma forma, se você DELETE uma linha com um ID menor do que o já visto, os resultados dessa abordagem não serão alterados, enquanto OFFSET irá pular uma linha não vista. No entanto, não há diferença para tabelas somente anexadas com chaves geradas.

Se você sabe de antemão que o cliente vai querer todo o conjunto de resultados, a coisa mais eficiente a fazer é simplesmente enviar o conjunto de resultados inteiro sem esse negócio de paginação. É onde eu faria usar um cursor. Leia as linhas do banco de dados e envie-as para o cliente tão rápido quanto o cliente as aceitar. Essa API precisaria definir limites sobre a lentidão permitida ao cliente para evitar carga excessiva de back-end; para um cliente lento, eu provavelmente mudaria para paginação (como descrito acima) ou transferiria todo o resultado do cursor para um arquivo temporário e fecharia a conexão do banco de dados.

Avisos importantes :
  • Requer um UNIQUE restrição / UNIQUE index ou PRIMARY KEY ser confiável
  • Diferente comportamento de modificação simultânea para limite/deslocamento, veja acima