A saída de explicação do MySQL é bastante direta. O PostgreSQL é um pouco mais complicado. Também não consegui encontrar um bom recurso que o explique.
Você pode descrever o que exatamente o explain está dizendo ou pelo menos me apontar na direção de um bom recurso?
postgresql
kjg
fonte
fonte
A parte que sempre achei confusa é o custo inicial versus custo total. Procuro no Google sempre que me esqueço, o que me traz de volta aqui, o que não explica a diferença, e é por isso que estou escrevendo esta resposta. Isso é o que eu obtive da documentação do Postgres
EXPLAIN
, explicado como eu o entendo.Aqui está um exemplo de um aplicativo que gerencia um fórum:
Aqui está a explicação gráfica do PgAdmin:
(Quando estiver usando o PgAdmin, você pode apontar o mouse para um componente para ler os detalhes de custo.)
O custo é representado como uma tupla, por exemplo, o custo de
LIMIT
écost=0.00..3.39
e o custo da varredura sequencialpost
écost=0.00..15629.12
. O primeiro número na tupla é o custo inicial e o segundo número é o custo total . Como useiEXPLAIN
e não useiEXPLAIN ANALYZE
, esses custos são estimativas, não medidas reais.Como complicação, os custos de cada nó "pai" incluem os custos de seus nós filhos. Na representação de texto, a árvore é representada por indentação, por exemplo,
LIMIT
é um nó pai eSeq Scan
é seu filho. Na representação do PgAdmin, as setas apontam do filho para o pai - a direção do fluxo de dados - o que pode ser contra-intuitivo se você estiver familiarizado com a teoria dos grafos.A documentação diz que os custos incluem todos os nós filhos, mas observe que o custo total do pai
3.39
é muito menor do que o custo total do filho15629.12
. O custo total não é inclusivo porque um componente comoLIMIT
não precisa processar toda a sua entrada. Veja oEXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;
exemplo na documentação do PostgresEXPLAIN
.No exemplo acima, o tempo de inicialização é zero para ambos os componentes, porque nenhum dos componentes precisa fazer qualquer processamento antes de começar a gravar linhas: uma varredura sequencial lê a primeira linha da tabela e a emite. O
LIMIT
lê sua primeira linha e a emite.Quando um componente precisaria fazer muito processamento antes de começar a produzir qualquer linha? Existem várias razões possíveis, mas vamos ver um exemplo claro. Aqui está a mesma consulta de antes, mas agora contém uma
ORDER BY
cláusula:E graficamente:
Mais uma vez, a varredura sequencial ativada
post
não tem custo inicial: ela começa a produzir linhas imediatamente. Mas a classificação tem um custo inicial significativo23283.24
porque precisa classificar a tabela inteira antes que possa produzir até mesmo uma única linha . O custo total da classificação23859.27
é apenas um pouco maior do que o custo inicial, refletindo o fato de que, uma vez que todo o conjunto de dados foi classificado, os dados classificados podem ser emitidos muito rapidamente.Observe que o tempo de inicialização do
LIMIT
23283.24
é exatamente igual ao tempo de inicialização do tipo. Isso não ocorre porqueLIMIT
ele mesmo tem um alto tempo de inicialização. Na verdade, ele tem tempo de inicialização zero por si só, masEXPLAIN
acumula todos os custos filhos de cada pai, de modo que oLIMIT
tempo de inicialização inclui a soma dos tempos de inicialização de seus filhos.Esse acúmulo de custos pode dificultar o entendimento do custo de execução de cada componente individual. Por exemplo, nosso
LIMIT
tem tempo de inicialização zero, mas isso não é óbvio à primeira vista. Por esse motivo, várias outras pessoas criaram um link para o explain.depesz.com , uma ferramenta criada por Hubert Lubaczewski (também conhecido como depesz) que ajuda a entenderEXPLAIN
, entre outras coisas, subtraindo os custos dos filhos dos custos dos pais. Ele menciona algumas outras complexidades em uma curta postagem no blog sobre sua ferramenta.fonte
Ele é executado do mais recuado para o menos recuado e, acredito, da parte inferior da planta para o topo. (Portanto, se houver duas seções recuadas, a que está mais abaixo na página é executada primeiro e, quando se encontram, a outra é executada e a regra que as une é executada.)
A ideia é que em cada etapa haja 1 ou 2 conjuntos de dados que chegam e são processados por alguma regra. Se for apenas um conjunto de dados, a operação é feita para esse conjunto de dados. (Por exemplo, verifique um índice para descobrir quais linhas você deseja, filtre um conjunto de dados ou classifique-o.) Se dois, os dois conjuntos de dados são as duas coisas que são indentadas posteriormente e são unidas pela regra que você vê. O significado da maioria das regras pode ser razoavelmente fácil de adivinhar (especialmente se você leu um monte de planos de explicação antes), no entanto, você pode tentar verificar itens individuais olhando na documentação ou (mais fácil) apenas jogando a frase em Google junto com algumas palavras-chave como
EXPLAIN
.Obviamente, essa não é uma explicação completa, mas fornece contexto suficiente para que você possa descobrir o que quiser. Por exemplo, considere este plano de um banco de dados real:
Tente ler você mesmo e veja se faz sentido.
O que eu li é que o banco de dados primeiro verifica o
id_orderitem_productid
índice, usando-o para encontrar as linhas que desejaorderitem
, depois classifica o conjunto de dados usando uma classificação rápida (a classificação usada mudará se os dados não couberem na RAM) e, em seguida, deixa isso de lado.Em seguida, ele faz
orditematt_attributeid_idx
a varredura para encontrar as linhas que desejaorderitemattribute
e, em seguida, classifica esse conjunto de dados usando uma classificação rápida.Em seguida, ele pega os dois conjuntos de dados e os mescla. (Uma união de mesclagem é uma espécie de operação de "compactação" em que percorre os dois conjuntos de dados classificados em paralelo, emitindo a linha unida quando eles correspondem.)
Como eu disse, você trabalha da parte interna à parte externa, de baixo para cima.
fonte
Também está disponível uma ferramenta auxiliar online, Depesz , que destacará onde estão as partes caras dos resultados da análise.
também tem um, aqui estão os mesmos resultados , que para mim tornam mais claro onde está o problema.
fonte
O PgAdmin mostrará uma representação gráfica do plano de explicação. Alternar entre os dois pode realmente ajudá-lo a entender o que significa a representação de texto. No entanto, se você apenas deseja saber o que ele está fazendo, pode sempre usar a GUI.
fonte
A documentação oficial do PostgreSQL fornece uma explicação interessante e completa sobre como entender a saída de explain.
fonte
Se você instalar o pgadmin, há um botão Explicar que além de fornecer a saída de texto desenha diagramas do que está acontecendo, mostrando os filtros, classificações e mesclagens de subconjuntos que considero muito úteis para ver o que está acontecendo.
fonte