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

devo ativar o agrupamento de instruções c3p0?


Não me lembro de imediato se o Hibernate realmente armazena instâncias PreparedStatement ou depende do provedor de conexão para reutilizá-las. (Uma verificação rápida do BatcherImpl sugere que ele reutilize o último PreparedStatement se estiver executando o mesmo SQL várias vezes seguidas)

Eu acho que o ponto que a documentação do c3p0 está tentando fazer é que, para muitos drivers JDBC, um PreparedStatement não é útil:alguns drivers acabarão simplesmente emendando os parâmetros no lado do cliente e passando a instrução SQL construída para o banco de dados de qualquer maneira . Para esses drivers, PreparedStatements não são nenhuma vantagem, e qualquer esforço para reutilizá-los é desperdiçado. (O Postgresql JDBC FAQ diz que este era o caso do Postgresql antes da versão 3 do protocolo servidor e há informações mais detalhadas na documentação).

Para drivers que lidam com PreparedStatements de forma útil, ainda é provavelmente necessário reutilizar as instâncias de PreparedStatement para obter algum benefício. Por exemplo, se o driver implementar:
  • Connection.prepareStatement(sql) - crie uma instrução do lado do servidor
  • PreparedStatement.execute(..) etc - execute essa instrução do lado do servidor
  • PreparedStatement.close() - desaloque a instrução do lado do servidor

Dado isso, se o aplicativo sempre abre uma instrução preparada, executa-a uma vez e depois a fecha novamente, ainda nenhum benefício; na verdade, pode ser pior, já que agora existem potencialmente mais viagens de ida e volta. Portanto, o aplicativo precisa manter as instâncias PreparedStatement. Obviamente, isso leva a outro problema:se o aplicativo travar demais e cada instrução do lado do servidor consumir alguns recursos, isso poderá levar a problemas no lado do servidor. No caso em que alguém está usando o JDBC diretamente, isso pode ser gerenciado por algumas instruções conhecidas por serem reutilizáveis ​​e, portanto, são preparadas; alguns não são e apenas usam instâncias de instrução transitórias. (Isso está pulando o outro benefício das instruções preparadas:lidar com o escape de argumentos)

Portanto, é por isso que o c3p0 e outros pools de conexão também prepararam caches de instrução - ele permite que o código do aplicativo evite lidar com tudo isso. As instruções geralmente são mantidas em algum pool LRU limitado, portanto, as instruções comuns reutilizam uma instância PreparedStatement.

As peças finais do quebra-cabeça são que os próprios drivers JDBC podem decidir ser inteligentes e fazer isso; e os próprios servidores também podem decidir ser espertos e detectar um cliente enviando uma declaração que é estruturalmente semelhante a uma anterior.

Dado que o Hibernate não mantém um cache de instâncias PreparedStatement, você precisa que o c3p0 faça isso para obter o benefício delas. (Que deve ser reduzida a sobrecarga para instruções comuns devido à reutilização de planos em cache). Se o c3p0 não armazenar em cache as instruções preparadas, o driver apenas verá o aplicativo preparando uma instrução, executando-a e fechando-a novamente. Parece que o driver JDBC tem uma configuração de "limite" para evitar a sobrecarga do servidor de preparação/execução no caso em que o aplicativo sempre faz isso. Então, sim, você precisa ter c3p0 para fazer cache de instruções.

Espero que ajude, desculpe é um pouco prolixo. A resposta é sim .