Meio ano atrás
Nos últimos meses, fizemos sobre ele
E agora estamos prontos para falar sobre os novos recursos que você pode usar.
Suporte para diferentes formatos de plano
Planeje a partir do log, junto com a solicitação
Diretamente do console, selecionamos o bloco inteiro, começando pela linha com Texto da Consulta, com todos os espaços iniciais:
Query Text: INSERT INTO dicquery_20200604 VALUES ($1.*) ON CONFLICT (query)
DO NOTHING;
Insert on dicquery_20200604 (cost=0.00..0.05 rows=1 width=52) (actual time=40.376..40.376 rows=0 loops=1)
Conflict Resolution: NOTHING
Conflict Arbiter Indexes: dicquery_20200604_pkey
Tuples Inserted: 1
Conflicting Tuples: 0
Buffers: shared hit=9 read=1 dirtied=1
-> Result (cost=0.00..0.05 rows=1 width=52) (actual time=0.001..0.001 rows=1 loops=1)
... e jogue tudo copiado direto no campo do plano, sem separar nada:
Na saída, também recebemos um bônus para o plano desmontado guia de contexto, onde o nosso pedido é apresentado em toda a sua glória:
JSON e YAML
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT * FROM pg_class;
"[
{
"Plan": {
"Node Type": "Seq Scan",
"Parallel Aware": false,
"Relation Name": "pg_class",
"Alias": "pg_class",
"Startup Cost": 0.00,
"Total Cost": 1336.20,
"Plan Rows": 13804,
"Plan Width": 539,
"Actual Startup Time": 0.006,
"Actual Total Time": 1.838,
"Actual Rows": 10266,
"Actual Loops": 1,
"Shared Hit Blocks": 646,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
},
"Planning Time": 5.135,
"Triggers": [
],
"Execution Time": 2.389
}
]"
Mesmo com aspas externas, como cópias do pgAdmin, mesmo sem - jogamos no mesmo campo, a saída é beleza:
Visualização avançada
Tempo de Planejamento / Tempo de Execução
Agora você pode ver melhor onde foi o tempo extra ao executar a consulta:
Tempo de E/S
Às vezes, você tem que lidar com uma situação em que, em termos de recursos, parece que não foi lido e escrito muito, mas parece que o tempo de execução é incongruentemente grande por algum motivo.
Tem que ser dito aqui:Ah, provavelmente naquele momento o disco do servidor estava muito sobrecarregado, por isso demorou tanto para ler!"Mas de alguma forma não é muito preciso...
Mas pode ser determinado de forma absolutamente confiável. O fato é que entre as opções de configuração do servidor PG existem track_io_timing
Habilita operações de E/S temporizadas. Essa configuração está desativada por padrão, pois exige que o sistema operacional consulte constantemente a hora atual, o que pode tornar as coisas significativamente mais lentas em algumas plataformas. Você pode usar o utilitário pg_test_timing para estimar a sobrecarga de tempo em sua plataforma. As estatísticas de I/O podem ser obtidas através da visualização pg_stat_database, na saída EXPLAIN (quando o parâmetro BUFFERS é usado) e por meio da visualização pg_stat_statements.
Esta opção também pode ser ativada em uma sessão local:
SET track_io_timing = TRUE;
Bem, agora a melhor parte é que aprendemos a entender e exibir esses dados, levando em consideração todas as transformações da árvore de execução:
Aqui você pode ver que de 0.790ms do tempo total de execução, 0.718ms levou a leitura de uma página de dados, 0.044ms - gravação e apenas 0.028ms foi gasto em todas as outras atividades úteis!
Futuro com PostgreSQL 13
Para obter uma visão geral completa das novidades, consulte
Buffers de planejamento
A contabilização de recursos alocados para o agendador é refletida em outro patch que não está relacionado a pg_stat_statements. EXPLAIN com a opção BUFFERS relatará o número de buffers usados durante a fase de planejamento:
Seq Scan on pg_class (actual rows=386 loops=1) Buffers: shared hit=9 read=4 Planning Time: 0.782 ms Buffers: shared hit=103 read=11 Execution Time: 0.219 ms
classificação incremental
Nos casos em que é necessária a ordenação por muitas chaves (k1, k2, k3…), o planejador pode agora aproveitar o fato de saber que os dados já estão ordenados por várias das primeiras chaves (por exemplo, k1 e k2). Nesse caso, você não pode reordenar todos os dados novamente, mas sim dividi-los em grupos sucessivos com os mesmos valores de k1 e k2 e “reclassificá-los” pela chave k3.
Assim, toda a classificação se divide em várias classificações sucessivas de tamanho menor. Isso reduz a quantidade de memória necessária e também permite que você retorne os primeiros dados antes que toda a classificação seja concluída.
Incremental Sort (actual rows=2949857 loops=1) Sort Key: ticket_no, passenger_id Presorted Key: ticket_no Full-sort Groups: 92184 Sort Method: quicksort Memory: avg=31kB peak=31kB -> Index Scan using tickets_pkey on tickets (actual rows=2949857 loops=1) Planning Time: 2.137 ms Execution Time: 2230.019 ms
Melhorias de UI/UX
Capturas de tela estão por toda parte!
Agora, em cada guia, há uma oportunidade de rapidamente tirar captura de tela da guia para a área de transferência para toda a largura e profundidade da guia - "visão" superior direito:
Na verdade, a maioria das fotos para esta publicação foram obtidas dessa maneira.
Recomendações sobre nós
Não há apenas mais deles, mas sobre cada um você pode
Removendo do arquivo
Alguns pediram a capacidade de exclua "absolutamente" mesmo planos que não estão publicados no arquivo - por favor, basta clicar no ícone correspondente:
Bem, não vamos esquecer que temos
Fonte: habr.com