Aumentando performance nos INSERTS e UPDATES PostgreSQL
- Fazer vários INSERTs e UPDATEs em apenas uma consulta, simultaneamente
- Fazer vários INSERTs e UPDATEs usando o "Batch Update"
- Usar o comando COPY ao invés de INSERT
- Usar Prepared Statements no servidor
- Usar Prepared Statements no cliente
- Ter o mínimo de índices possíveis
- Ao fazer um UPDATEs, alterar apenas colunas que não são indexadas (Chamado de hot update! Apenas no PostgreSQL, o MySQL InnoDB não sofre dessa penalidade)
- Particionar a tabela
- Criar tabela com UNLOGGED (cuidado!)
- Fazer INSERTs e UPDATEs em paralelo (rodando as várias consultas em várias conexões diferentes ao mesmo tempo, um connection pool ajuda muito)
- Desabilite o fsync (perigoso!)
- Desabilite o synchronous_commit (cuidado!)
- Não tenha mais de 1000 tabelas (thumb rule)
Usando Prepared Statements no servidor
Os PREPARED STATEMENTS são consultas SQL pré preparadas, um esqueleto de uma consulta sem seus valores. Um prepared statement tem interrogações nestes parâmetros, mais ou menos com essa cara:
INSERT INTO tabela (id, nome, idade)VALUES (?, ?, ?)
Ou mais ou menos essa cara:
Os PREPARED STATEMENTS são muito conhecidos como forma de impedir que SQL injections aconteçam no banco, mas o seu maior objetivo não é esse, pelo menos não para os prepared statements no Servidor. Normalmente, ao enviar uma query ao banco de dados, o driver envia ao banco um textão contendo a consulta inteira. O banco por sua vez faz o parse desse texto, confere se há algum erro de sintaxe, pra só então executar o comando. Com o prepared statement no servidor, é preciso primeiro enviar a consulta desejada ao servidor, mas com "?" nos valores a definir, conforme o exemplo abaixo: Após o envio do "esqueleto" da consulta, você poderá substituir os ? por valores e finalmente enviar a consulta ao banco. Por trás dos panos o cliente enviará apenas os valores, e não a consulta inteira como de costume. Isso alivia o banco em 2 pontos: reduz o processamento gasto com parse do texto para código e reduz o tráfego entre o cliente o servidor. Isso significa que o Prepared Statement no servidor ajuda apenas quando temos consultas repetidas que usam um mesmo esqueleto. É um caso perfeito para INSERTS em massa e também SELECTS. Prós: Contras: Descubra todos os Prepared Statements abertos na conexão atual com: ATENÇÃO - Não é possível verificar os prepared statements de outras conexões. Essa informação não pode ser obtida. Os Prepared Statements são uma boa ferramenta de otimização nos casos em que a consulta/inserção/atualização é sempre igual, mudando apenas os parâmetros, por exemplo: Confira aqui a documentação oficial sobre prepared statements. O JDBC cria automaticamente prepared statements no servidor se a conexão preparar a mesma consulta 5 vezes (ou um número de vezes definido no parâmetro prepareThreshold). Estou procurando formas de fazer cache de Prepared Statements no PostgreSQL com o Hikari. O HikariCP por si só não faz cache de Statements. Implicit Caching JDBC HikariCP Prepared Statement Oracle JDBC Developer Guide - Statement Caching Melhorando performance de INSERTs Melhorando performance de INSERTs - Discussão no Stack Overflow Melhorando performance de INSERTs Tunando seu PostgreSQL Exemplo de configuração do HikariCP Parâmetros de configuração do JDBC com Prepared Statements Considerações sobre Prepared Statement com o JDBC. Server side ou Client side? Artigo sensacional sobre performance de INSERTs no PostgreSQL e MySQL Aumentando performance do JDBC com batches Dicas para aumentar performance de insert no PostgreSQL Discussão sobre inserts eficientes com o JDBC Discussão sobre inserts eficientes com o JDBC (mysql) Documentação oficial sobre o comando PREPARE Documentação sobre server prepared statements do PGJDBC Lições aprendidas ao escalar PostgreSQL em 5 anosFazendo prepared statements no servidor implicitamente
Fazendo prepared statements no servidor explicitamente
-- Exemplo de INSERT
Reduz o tráfego de rede entre o cliente e o servidor
Reduz o processamento de parse
Promove proteção contra SQL Injection
Os Prepared Statements ocupam um pedaço na memória RAM
Criar Prepared Statements a toda hora prejudica a performanceSELECT *
INSERT INTO tabela (x, y, z)
https://www.postgresql.org/docs/current/sql-prepare.htmlComo o JDBC lida com Prepared Statements?
Fazendo cache de Prepared Statements no JDBC com Hikari Connection Pool
https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
https://stackoverflow.com/questions/21716839/prepared-statement-cache-with-mysql-jdbc
https://stackoverflow.com/questions/12167108/using-oracle-jdbc-driver-implicit-caching-feature
https://stackoverflow.com/questions/45546531/hikaricp-prepared-statement-cacheReferências
https://docs.oracle.com/cd/B10501_01/java.920/a96654/stmtcach.htm
https://github.com/vitaly-t/pg-promise/wiki/Performance-Boost
https://stackoverflow.com/questions/41074557/how-to-improve-postgresql-performance-on-insert
https://www.petefreitag.com/item/454.cfm
https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
https://pt.stackoverflow.com/questions/55607/hikaricp-unable-to-get-driver-for-jdbc-url
https://stackoverflow.com/q/32286518/2789895
https://stackoverflow.com/questions/32297503/whats-the-life-span-of-a-postgresql-server-side-prepared-statement
https://medium.com/@jerolba/persisting-fast-in-database-jdbc-76912ec2ef42
https://dzone.com/articles/performant-batch-inserts-using-jdbc
https://dzone.com/articles/13-tips-to-improve-postgresql-insert-performance
https://stackoverflow.com/questions/3784197/efficient-way-to-do-batch-inserts-with-jdbc/17062396
https://stackoverflow.com/questions/2993251/jdbc-batch-insert-performance
https://www.postgresql.org/docs/current/sql-prepare.html
https://jdbc.postgresql.org/documentation/head/server-prepare.html
https://onesignal.com/blog/lessons-learned-from-5-years-of-scaling-postgresql/