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

Qual é a vida útil de uma instrução preparada do lado do servidor PostgreSQL


Então, sua pergunta finalmente se resume a "como java.sql.PreparedStatement joga com o PostgreSQL." Veja a resposta em "como isso funciona com os planos preparados pelo servidor" no final.

Aqui está a resposta:isso depende do driver JDBC que você usa.

TL;DR :em drivers modernos, a instrução preparada pelo servidor vive até que a conexão morra ou até que a instrução seja despejada por outra (remoção de LRU regular).

Nota:O servidor PostgreSQL não pode compartilhar instruções preparadas em conexões de banco de dados, portanto, o melhor driver JDBC que pode fazer é manter o plano armazenado em cache em cada conexão.

Observação:a especificação JDBC exige o uso de ?, ? para marcadores de vínculo, enquanto o servidor deseja $1, $2 assim, os drivers JDBC também armazenam os chamados textos SQL analisados.

Existem dois drivers JDBC conhecidos:pgjdbc e pgjdbc-ng

pgjdbc


https://github.com/pgjdbc/pgjdbc

Desde pgjdbc 9.4-1202 ele armazena automaticamente os planos do lado do servidor ao usar PreparedStatement .Nota:as instruções são armazenadas em cache mesmo se você close() a PreparedStatement .Para chegar à preparação do lado do servidor, você precisa executar a consulta 5 vezes (que pode ser configurada via prepareThreshold ).

Atualmente, o cache é implementado por conexão. Por padrão, o pgjdbc armazena em cache 256 (preparedStatementCacheQueries ) e até preparedStatementCacheSizeMiB de consultas. Esta é uma configuração conservadora, então você pode querer ajustá-la. Consulte a documentação para a descrição das propriedades. O cache inclui instruções analisadas e preparadas pelo servidor.

problema do github:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng


https://github.com/impossibl/pgjdbc-ng

Eu não gosto de pgjdbc-ng, no entanto, parece que ele faz a análise (o tamanho padrão do cache é 250 consultas) e preparação do servidor (o tamanho padrão do cache é 50 consultas). O suporte de instruções preparadas do lado do servidor chegou em 24 de fevereiro de 2014, portanto, se você usar uma versão um pouco recente, poderá obter o cache de instruções.

Nota:se você acidentalmente usar consultas muito longas, você pode clicar em OutOfMemory já que o pgjdbc-ng não pode remover entradas com base no número de bytes retidos.

O cache é por conexão, portanto, é usado de forma transparente mesmo se você fechar instruções.

Não posso dizer muito sobre o desempenho do pgjdbc-ng, embora desde a última vez que tentei jogar o jmh nele, ele falhou com exceções aleatórias.

problema do github:https://github.com/impossibl/pgjdbc-ng/pull/ 69

Planos preparados para servidor


PostgreSQL tem PREPARE e DEALLOCATE comandos para referenciar a instrução ao enviar EXEC sobre o fio. Ele otimiza duas coisas:
  1. Ao usar PREPARE d (em outras palavras, preparada pelo servidor), o cliente não precisa enviar o texto da consulta repetidamente. Ele apenas envia um nome de consulta curto e os valores para variáveis ​​de ligação.
  2. Desde 9.2, o banco de dados ainda tenta replanejar as primeiras execuções de uma consulta. Ele faz isso para testar se a consulta precisa de vários planos ou se o plano genérico é bom o suficiente. Eventualmente (imediatamente se a consulta não tiver parâmetros), o banco de dados pode mudar para um plano genérico .
  3. Desde 12, há uma configuração para forçar TODAS as instruções preparadas pelo servidor a serem executadas com planos genéricos ou personalizados:plan_cache_mode =auto | force_custom_plan | force_generic_plan

Em outras palavras, PreparedStatement otimiza tanto a análise de consulta no lado do JDBC quanto o planejamento de consulta no lado do banco de dados.

Mais informações aqui:http://blog.endpoint .com/2014/04/custom-plans-prepared-statements-in.html

Declarações preparadas em PL/pgSQL


De acordo com a documentação, PostgreSQL caches planos para consultas usadas em PL/pgSQL. Isso acontece após algumas execuções (3 ou 5, não me lembro do limite exato), portanto, depois de criar o procedimento armazenado, ele pode ficar um pouco lento, no entanto, ele alternará para os planos em cache (desde que o banco de dados concorde em usar o plano genérico para uma consulta específica).

Em outras palavras, para obter "planos de execução em cache", você precisa usar o driver JDBC atualizado ou pode agrupar todas as suas consultas em procedimentos armazenados. normalmente muito mais curtas do que as consultas que compõem o procedimento.