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

Usando cursores para paginação no PostgreSQL


Os cursores são uma escolha razoável para paginação em aplicativos de intranet menores que funcionam com grandes conjuntos de dados, mas você precisa estar preparado para descartá-los após um tempo limite. Os usuários gostam de passear, almoçar, sair de férias por duas semanas, etc, e deixar seus aplicativos em execução. Se for um aplicativo baseado na web, há até a questão do que é "executar" e como saber se o usuário ainda está por perto.

Eles não são adequados para aplicativos de grande escala com altas contagens de clientes e clientes que vêm e vão quase aleatoriamente, como em aplicativos baseados na Web ou APIs da Web. Eu não recomendaria usar cursores em seu aplicativo, a menos que você tenha uma contagem de clientes bastante pequena e taxas de solicitação muito altas ... nesse caso, enviar pequenos lotes de linhas será muito ineficiente e você deve pensar em permitir solicitações de intervalo etc.

Os cursores têm vários custos. Se o cursor não estiver WITH HOLD você deve manter uma transação aberta. A transação aberta pode impedir que o autovacuum faça seu trabalho corretamente, causando inchaço na tabela e outros problemas. Se o cursor for declarado WITH HOLD e a transação não é mantida aberta, você tem que pagar o custo de materializar e armazenar um conjunto de resultados potencialmente grande - pelo menos, acho que é assim que os cursores de espera funcionam. A alternativa é igualmente ruim, mantendo a transação implicitamente aberta até que o cursor seja destruído e evitando que as linhas sejam limpas.

Além disso, se você estiver usando cursores, não poderá devolver as conexões a um pool de conexões. Você precisará de uma conexão por cliente. Isso significa que mais recursos de back-end são usados ​​apenas para manter o estado da sessão e define um limite superior muito real no número de clientes que você pode manipular com uma abordagem baseada em cursor.

Há também a complexidade e a sobrecarga de gerenciar uma configuração baseada em cursor com estado em comparação com uma abordagem de pool de conexão sem estado com limite e deslocamento. Você precisa que seus cursores expirem após um tempo limite ou você enfrenta uso de recursos potencialmente ilimitado no servidor e precisa acompanhar quais conexões têm quais cursores para quais conjuntos de resultados para quais usuários....

Em geral, apesar de ser bastante ineficiente, LIMIT e OFFSET pode ser a melhor solução. Muitas vezes, pode ser melhor pesquisar a chave primária em vez de usar OFFSET , no entanto.

A propósito, você estava olhando a documentação de cursores em PL/pgSQL. Você deseja cursores de nível SQL normais para este trabalho.

Os cursores exigem que uma conexão de banco de dados seja deixada aberta?

Sim.

Os cursores são executados dentro de uma transação, bloqueando recursos até que sejam "fechados"?

Sim, a menos que sejam WITH HOLD , nesse caso eles consomem outros recursos do banco de dados.

Existem outras "pegadinhas" que eu não conheço?

Sim, como o acima deve explicar.