Estou executando um Aurora PostgreSQL em uma db.x2g.2xlarge
instância. A simples criação de tabela temporária apareceu como a terceira maior espera, o que me surpreende, pois esperava que fosse uma das consultas mais leves.
A consulta é chamada em uma transação:
CREATE TEMP TABLE identifiers_to_resolve (
scheme_pk BIGINT,
host_pk BIGINT,
port INT NOT NULL,
scheme_specific_part VARCHAR NOT NULL,
index INTEGER NOT NULL
) ON COMMIT DROP;
Quero usar a tabela temporária como um armazenamento temporário na transação durante uma consulta mais complicada.
As estatísticas dos insights de desempenho:
- Carga por espera (AAS): 0,42
- Chamadas/s: 123,64
- Acertos pretos/s: 48.499,58
- Gravações pretas/seg: 16,32
- Latência média ms/chamada: 3,24
- Preto atinge/liga 329,27
- Blk escreve/chama 0,13
Todas as outras estatísticas são 0.
Os insights de desempenho registram as esperas como quase todas as "CPU". Captura de tela anexada.
Acho que 123 chamadas por segundo é uma taxa bastante baixa e estou surpreso que esteja sobrecarregando tanto o banco de dados e afetando tantos blocos. Pelos casos de uso que li sobre tabelas temporárias, esperava que tivessem menor impacto.
É típico que a criação de tabelas temporárias cause tanta espera na CPU?
Resumindo meus comentários em uma resposta:
Criar e destruir tabelas temporárias envolve operações de catálogo de arquivos e sistema que levam tempo.
No exemplo acima, isso é visível na criação da tabela temporária, mas também no commit, quando ela é excluída.
A tabela temporária mais "permanente" criada com "on commit delete rows" evita a maioria dessas operações, pois é simplesmente truncada no final da transação. A criação e exclusão de tabelas são ignoradas, por isso é muito mais rápido.
Se você usar um pooler de conexões, poderá criar as tabelas temporárias quando a conexão for aberta e mantê-las para todos os usos subsequentes dessa conexão. Basta criá-los com "ON COMMIT DELETE ROWS" para que a tabela seja truncada após cada uso.
Se o seu pool usar DISCARD ALL ao obter uma conexão já aberta e passá-la para um cliente, isso também descarta tabelas temporárias, portanto deve ser alterado. Infelizmente, não há como descartar tudo, exceto tabelas temporárias, com um comando, e geralmente não é uma boa ideia manter algum estado persistente quando as conexões são reutilizadas, portanto, isso requer um pouco de reflexão.
Quando várias conexões criam tabelas temporárias com o mesmo nome, elas não são a mesma tabela. Eles têm o mesmo nome, mas cada tabela temporária existe apenas nos catálogos do sistema da conexão que a abriu e cada uma possui seus próprios arquivos em disco.
Portanto, o motivo pelo qual eles não verão as linhas um do outro não é devido às regras de visibilidade da transação... mas simplesmente porque são tabelas diferentes.