Melhores práticas para aprimorar a conformidade, a estabilidade e o desempenho de instâncias do ApsaraDB RDS for PostgreSQL.
Pool de conexões
Configure parâmetros do pool de conexões
Use objetos PreparedStatement para armazenar instruções SQL em cache no pool de conexões. Essa abordagem elimina análises sintáticas completas (hard parses), reduz o uso de CPU e melhora o desempenho da instância.
Minimize as conexões ociosas para diminuir o consumo de memória, aumentar a eficiência da função GetSnapshotData() e otimizar o desempenho geral do sistema.
Ative o pool de conexões na aplicação para evitar a sobrecarga causada por conexões de curta duração. Caso a aplicação não ofereça suporte nativo a pools de conexões, insira um componente intermediário entre ela e a instância RDS, como PgBouncer ou Pgpool-II.
Defina os seguintes parâmetros para o pool de conexões:
|
Parâmetro |
Valor recomendado |
Descrição |
|
|
1 |
Quantidade mínima de conexões ociosas. Definir este valor como 1 reduz o número de conexões inativas. |
|
|
1 |
Quantidade máxima de conexões ociosas. Aplica-se apenas se o parâmetro estiver disponível, pois foi removido da maioria das implementações modernas de pools de conexão. |
|
|
60 minutos |
Tempo de vida máximo (TTL) por conexão. Reduz erros de falta de memória (OOM) causados por conexões frequentes ao RelCache. |
|
|
15 |
Limite máximo de conexões por pool. Adequado para a maioria das cargas de trabalho. Aumente este valor nos clientes de banco de dados somente se a instância precisar gerenciar mais conexões simultâneas do que o pool consegue atender. |
Configurações recomendadas por framework
As configurações abaixo aplicam-se aos frameworks de pool de conexões mais comuns. Elas não incluem ajustes de PreparedStatement; configure-os conforme os requisitos da aplicação.
HikariCP (recomendado para Java):
minimumIdle=1, maximumPoolSize=15, idleTimeout=600000 (10 minutes), maxLifetime=3600000 (60 minutes)
GORM (recomendado para Go):
sqlDB.SetMaxIdleConns(1), sqlDB.SetMaxOpenConns(15), sqlDB.SetConnMaxLifetime(time.Hour)
Druid (Java):
initialSize=1, minIdle=1, maxIdle=1, maxActive=15, testOnBorrow=false, testOnReturn=false, testWhileIdle=true, minEvictableIdleTimeMillis=600000 (10 minutes), maxEvictableIdleTimeMillis=900000 (15 minutes), timeBetweenEvictionRunsMillis=60000 (1 minute), maxWait=6000 (6 seconds)
Desempenho e estabilidade
Cada banco de dados corresponde a uma pasta no sistema de arquivos subjacente, onde tabelas, partições e índices são representados como arquivos. Se a quantidade de arquivos ultrapassar 20 milhões, a instância retornará um erro de espaço em disco esgotado. Divida o banco de dados ou consolide arquivos de tabelas de acordo com a carga de trabalho.
Prefira o comando
CREATE INDEX CONCURRENTLYpara criar índices em ambientes de produção. Isso evita o bloqueio de operações INSERT, UPDATE e DELETE na tabela alvo durante outras sessões.Em instâncias com PostgreSQL 12 ou superior, use
REINDEX CONCURRENTLYpara reconstruir índices. Para versões anteriores (PostgreSQL 11 ou inferior), crie um índice substituto comCREATE INDEX ... CONCURRENTLYe, em seguida, remova o índice original.Evite criar e excluir tabelas temporárias com frequência, pois isso aumenta a sobrecarga nas tabelas do sistema. Tenha cautela ao usar
ON COMMIT DROP. Na maioria dos casos, prefira a cláusulaWITHem vez de tabelas temporárias.O PostgreSQL 13 trouxe melhorias significativas para tabelas particionadas, operações
HashAggregateem cláusulasGROUP BYe consultas paralelas. Sempre que possível, atualize a instância para o PostgreSQL 13. Para mais detalhes, consulte Atualizar a versão principal do mecanismo de uma instância do ApsaraDB RDS for PostgreSQL.Desative o recurso de cursor caso não esteja mais em uso.
Para remover dados no nível de tabela, use
TRUNCATEem vez deDELETE, já que oTRUNCATEoferece desempenho muito superior.Agrupe instruções DDL em transações para permitir rollback se necessário. Mantenha as transações curtas: transações DDL longas bloqueiam leituras nos objetos afetados.
Para escrita massiva de dados, maximize o throughput usando
COPYou comandosINSERT INTO table VALUES (),(),...();com múltiplas linhas.
Versão secundária do mecanismo
Para utilizar slots de replicação, atualize a versão secundária do mecanismo para 20201230 ou posterior. Essa atualização habilita o recurso Logical Replication Slot Failover e permite configurar uma regra de alerta para a métrica Maximum Replication Slot Latency, evitando atrasos ou interrupções em assinaturas lógicas. Quando assinaturas lógicas sofrem atraso ou interrupção, os slots de replicação são perdidos e os registros de write-ahead logging (WAL) começam a acumular. Para mais informações, consulte Logical Replication Slot Failover e Gerenciar regras de alerta de uma instância do ApsaraDB RDS for PostgreSQL.
-
Para usar os recursos de log de auditoria ou Performance Insight, atualize a versão secundária do mecanismo para 20211031 ou posterior.
Quando
log_statementestá definido comoall, o desempenho melhora aproximadamente quatro vezes em cenários com mais de 50 conexões ativas, além de prevenir picos significativos no uso da CPU.
Monitoramento e alertas
Ative o Initiative Alert para habilitar as regras de alerta padrão fornecidas pelo recurso de monitoramento e alertas. Para mais detalhes, consulte Gerenciar alertas.
Configure o limiar de alerta de uso de memória entre 85% e 95%, ajustando-o conforme as características da carga de trabalho.
Solução de problemas
Para identificar as instruções SQL com maior consumo de recursos (Top SQL), consulte Localizar instruções SQL com maior consumo de recursos (Top SQL).
Para identificar as instruções SQL com maior consumo de recursos, consulte Localizar instruções SQL com maior consumo de recursos.
Design
Permissões
Siga o princípio do menor privilégio (PoLP) e gerencie permissões por schema ou função. Crie duas funções para cada instância: uma com permissões de leitura e escrita e outra apenas para leitura. Para mais informações, consulte Gerenciar permissões em uma instância do ApsaraDB RDS for PostgreSQL.
Se implementar separação de leitura e escrita na camada de aplicação, atribua a função de somente leitura aos clientes de banco de dados dedicados a leituras.
Tabelas
Alinhe os tipos de dados do schema com os tipos utilizados na aplicação e aplique regras de validação consistentes em todas as tabelas. Isso previne erros de incompatibilidade de tipos e garante o uso correto dos índices.
Para tabelas com dados históricos purgados regularmente, utilize particionamento por ano ou mês. Remova dados usando
DROPouTRUNCATEnas partições filhas; evite executarDELETEdiretamente nessas partições.-
Em tabelas com atualizações frequentes, defina
FILLFACTORcomo85durante a criação. Isso reserva 15% do armazenamento por página para atualizações quentes (hot updates), reduzindo a divisão de páginas.CREATE TABLE test123(id int, info text) WITH(FILLFACTOR=85); -
Adote as seguintes convenções de nomenclatura:
Tabelas temporárias: nomes devem começar com
tmp_Tabelas de partição filha: nomes devem terminar com o valor da chave de partição. Por exemplo, se a tabela pai for
tble estiver particionada por ano, as tabelas filhas serão nomeadas comotbl_2016,tbl_2017, e assim por diante.
Índices
O ApsaraDB RDS for PostgreSQL suporta os seguintes tipos de índice: B-tree, Hash, GIN, GiST, SP-GiST, BRIN, RUM, Bloom e PASE. Os tipos RUM, Bloom e PASE são extensões de índices.
Escolha do tipo de índice:
B-tree: Tipo de índice padrão. Os campos indexados não podem exceder 2.000 bytes no total. Caso o tamanho combinado ultrapasse esse limite, crie um índice baseado em função (como um índice hash) ou processe os dados com um analisador antes da indexação.
-
BRIN: Ideal para tabelas grandes cujos valores de coluna possuem uma ordenação linear natural, como timestamps, IDs autoincrementais ou dados de streaming. Índices BRIN são compactos e aceleram consultas de intervalo.
CREATE INDEX idx ON tbl USING BRIN(id);
Evite varreduras completas de tabela (full table scans), exceto quando for necessário analisar grandes conjuntos de dados. A maioria dos tipos de dados do PostgreSQL suporta indexação.
Convenções de nomenclatura de índices:
|
Tipo de índice |
Prefixo |
|
Índices de chave primária |
|
|
Índices únicos |
|
|
Índices comuns |
|
Tipos de dados e conjuntos de caracteres
Escolha tipos de dados adequados à natureza da informação armazenada. Evite usar tipos string para dados numéricos ou para dados que se encaixam naturalmente em estruturas de árvore; tipos apropriados aumentam a eficiência das consultas.
O ApsaraDB RDS for PostgreSQL oferece suporte a uma ampla variedade de tipos de dados, incluindo: Numeric, Floating-Point, Monetary, String, Character, Binary, Date/Time, Boolean, Enumerated, Geometry, Network Address, Bit String, Text Search, UUID, XML, JSON, Array, Composite, Range, Object identifier, row number, large object, ltree structure, Data Cube, geography, H-Store, pg_trgm module, PostGIS e HyperLogLog. O PostGIS suporta tipos como ponto, segmento de linha, superfície, caminho, latitude, longitude, raster e topologia. O HyperLogLog é uma estrutura de dados semelhante a um conjunto, de tamanho fixo, usada para contar valores distintos com precisão ajustável.
Defina LC_COLLATE como C em vez de UTF8. A collation C apresenta desempenho superior à UTF8. Se precisar usar a collation UTF8, especifique a classe de operador text_pattern_ops nos índices para dar suporte a consultas LIKE.
Stored procedures
Para lógicas de negócio complexas que exigem muitas idas e vindas entre a aplicação e o banco de dados, use stored procedures (como as baseadas em PL/pgSQL) ou funções internas para reduzir a interação entre aplicação e banco. O PostgreSQL suporta funções analíticas, agregadas, de janela, matemáticas e geométricas.
Consulta de dados
Prefira
COUNT(*)em vez deCOUNT(column_name)ouCOUNT(constants). OCOUNT(*)segue o padrão SQL-92 para contagem de linhas e inclui valores NULL. Já oCOUNT(column_name)exclui valores NULL, resultando em uma contagem diferente.-
Ao usar
COUNT(DISTINCT)em múltiplas colunas, envolva a lista de colunas entre parênteses:COUNT( (col1, col2, col3) )Como o
COUNT(DISTINCT)considera todos os valores NULL, ele produz o mesmo resultado queCOUNT(*). Evite o uso de
SELECT * FROM t. Especifique apenas as colunas necessárias para impedir o retorno de dados desnecessários.Não retorne conjuntos de resultados excessivamente grandes para os clientes de banco de dados, exceto em operações de extração, transformação e carga (ETL). Se uma consulta retornar um volume anormal de dados, verifique se o plano de execução está otimizado.
Em consultas de intervalo, use tipos de dados Range com índices GiST para melhorar o desempenho.
Se a aplicação executa frequentemente consultas que retornam muitas linhas, agrupe os resultados em lotes. Por exemplo, se uma consulta retorna 100 linhas, consolide-as em um único conjunto de resultados. Caso o acesso seja feito por ID, realize agregações periódicas por ID. Conjuntos menores reduzem o tempo de resposta.
Gerenciamento de instâncias
Ative o recurso SQL Explorer and Audit para consultar e exportar informações sobre execuções SQL, incluindo bancos acessados, status de execução e durações. Use esse recurso para diagnosticar a integridade das instruções SQL, solucionar problemas de desempenho e analisar tráfego. Para mais informações, consulte Usar o recurso SQL Explorer and Audit em uma instância do ApsaraDB RDS for PostgreSQL.
Para monitorar e registrar atividades na conta Alibaba Cloud — incluindo acessos via console, API e ferramentas de desenvolvedor — use o ActionTrail. Esse serviço registra ações como eventos que podem ser baixados pelo console do ActionTrail ou enviados para Logstores do Log Service ou buckets do Object Storage Service (OSS), permitindo análises de segurança, rastreamento de mudanças em recursos e auditorias de conformidade. Para mais detalhes, consulte O que é o ActionTrail?.
Revise todas as operações DDL antes de executá-las e programe alterações DDL para horários de baixa demanda.
Antes de confirmar transações que excluam ou modifiquem dados, execute uma instrução
SELECTpara validar as linhas afetadas. Se a lógica de negócio exigir a atualização de exatamente uma linha, adicioneLIMIT 1.-
Para operações DDL e outras que adquiram locks — como
VACUUM FULLeCREATE INDEX— defina um tempo limite de lock para evitar que elas bloqueiem consultas indefinidamente:BEGIN; SET LOCAL lock_timeout = '10s'; -- DDL statement; END; -
Use
EXPLAIN ANALYZEpara inspecionar o plano de execução de uma consulta. Diferente doEXPLAIN, oEXPLAIN ANALYZEexecuta a consulta de fato. Se o plano envolver operações DML (UPDATE, INSERT ou DELETE), envolva a instrução em uma transação e faça rollback após a inspeção para evitar alterações indesejadas nos dados:BEGIN; EXPLAIN (ANALYZE) <DML (UPDATE/INSERT/DELETE) SQL>; ROLLBACK; Para exclusões ou atualizações em larga escala, processe os dados em lotes, executando cada lote em sua própria transação. Excluir ou atualizar todas as linhas em uma única transação gera uma grande quantidade de dados obsoletos (junk data).