Pergunta

saída de explicar MySQL é bastante simples. PostgreSQL do é um pouco mais complicado. Eu não tenho sido capaz de encontrar um bom recurso que explica que quer.

Você pode descrever o que exatamente explicar é dizer ou pelo menos me aponte na direção de um bom recurso?

Foi útil?

Solução

Explaining_EXPLAIN.pdf poderia ajudar também.

Outras dicas

A parte que eu sempre achei confuso é o custo inicial vs custo total. I Google esta cada vez que eu esquecê-la, o que me traz de volta para aqui, que não explica a diferença, que é por isso que eu estou escrevendo esta resposta. Isto é o que eu adquirida a partir da Postgres EXPLAIN documentação , < strong> explicou como eu o entendo.

Aqui está um exemplo de um aplicativo que gerencia um fórum:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Aqui está a explicação gráfica de PgAdmin:

 explicação gráfica da primeira consulta

(Quando você estiver usando PgAdmin, você pode apontar o mouse para um componente para ler os detalhes de custo.)

O custo é representado como um tuplo, v.g. o custo do LIMIT é cost=0.00..3.39 e o custo de digitalização sequencialmente post é cost=0.00..15629.12. O primeiro número na tupla é a custo de inicialização e o segundo número é a custo total . Porque eu usei EXPLAIN e não EXPLAIN ANALYZE, estes custos são estimativas, e não medidas reais.

  • custo Startup é um conceito complicado. Ele não apenas representam a quantidade de tempo antes que o componente inicia . Ela representa a quantidade de tempo entre o momento do início do componente executoras (leitura de dados) e quando o componente gera a primeira linha .
  • O custo total é todo o tempo de execução do componente, a partir de quando se começa a ler em dados para quando ele terminar de escrever sua saída.

Como complicação, os custos de cada nó "pai" inclui o custo do de seus nós filho. Na representação de texto, a árvore é representado por recuo, por exemplo, LIMIT é um nó pai e Seq Scan é o seu filho. Na representação PgAdmin, as setas apontam da criança ao pai - a direção do fluxo de dados -. Que pode ser contra-intuitivo se você estiver familiarizado com a teoria dos grafos

A documentação diz que os custos estão incluídos todos os nós filhos, mas aviso que o custo total da 3.39 pai é muito menor do que o custo total dela é 15629.12 criança. custo total não é inclusivo porque um componente como LIMIT não precisa processar toda a sua entrada. Veja o exemplo EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; em Postgres EXPLAIN documentação .

No exemplo acima, o tempo de inicialização é zero para ambas as componentes, porque nem as necessidades de componentes para fazer qualquer processamento antes que ele começa a escrever linhas: uma varredura sequencial lê a primeira linha da tabela e a emite. O LIMIT lê sua primeira linha e, em seguida, emite-lo.

Quando é que uma necessidade componente para fazer um monte de processamento antes de poder começar a saída de todas as linhas? Há uma série de razões possíveis, mas Vamos olhar um exemplo claro. Aqui está a mesma consulta de antes, mas agora que contenha uma cláusula ORDER BY:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

E graficamente:

 explicação gráfica da segunda consulta

Mais uma vez, a varredura seqüencial em post não tem custo inicial: ele começa a produzir linhas imediatamente. Mas o tipo tem um 23283.24 significativo custo inicial porque tem que Classificar a tabela inteira antes que ele pode produzir até mesmo uma única linha . O custo total da 23859.27 tipo é apenas ligeiramente maior do que o custo inicial, refletindo o fato de que uma vez que todo o conjunto de dados foi classificado, os dados classificados pode ser emitido muitorapidamente.

Observe que o tempo de inicialização do LIMIT 23283.24 é exatamente igual ao tempo de inicialização do tipo. Isto não é porque a própria LIMIT tem um tempo de arranque elevado. Ele realmente tem o tempo de inicialização de zero, por si só, mas EXPLAIN enrola todos os custos de criança para cada um dos pais, de modo que o tempo de inicialização LIMIT inclui vezes a soma de inicialização de seus filhos.

Este conjunto de custos pode tornar difícil para entender o custo de execução de cada componente individual. Por exemplo, nosso LIMIT tem tempo de inicialização do zero, mas isso não é óbvio à primeira vista. Por esta razão, várias outras pessoas ligadas a explain.depesz.com , uma ferramenta criada por Hubert Lubaczewski (aka depesz ) que ajuda a entender EXPLAIN por - entre outras coisas - subtraindo a custos criança de custos pais. Ele menciona algumas outras complexidades em um curto post sobre sua ferramenta.

Ele executa a partir de mais recuado para menos recuado, e eu acredito que a partir do fundo do plano para o topo. (Então, se há duas seções ondulado, a um mais para baixo executa a primeira página, em seguida, quando eles se encontram os outros executa, a regra se juntando a eles executa.)

A idéia é que em cada etapa há 1 ou 2 conjuntos de dados que chegam e se processados ??por alguma regra. Se apenas um conjunto de dados, que a operação é feita para esse conjunto de dados. (Por exemplo varredura de um índice para descobrir quais linhas você quer, filtro de um conjunto de dados, ou classificá-lo.) Se dois, os dois conjuntos de dados são as duas coisas que são recuadas ainda mais, e eles são unidos pela regra que você vê. O significado da maioria das regras pode ser razoavelmente fácil de adivinhar (especialmente se você tiver lido um monte de explicar planos antes), mas você pode tentar verificar itens individuais ou vendo na documentação ou (mais fácil) por apenas jogando a frase em Google junto com algumas palavras-chave como EXPLAIN.

Esta não é, obviamente, uma explicação completa, mas fornece contexto suficiente para que você pode geralmente descobrir o que quiser. Por exemplo, considere este plano a partir de um banco de dados real:

explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';

------------------------------------------------------------------------------------------------------------------------------------------------------------

 Merge Join  (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
   Merge Cond: (a.orderid = b.orderid)
   ->  Sort  (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
         Sort Key: a.orderid
         Sort Method:  quicksort  Memory: 1695kB
         ->  Bitmap Heap Scan on orderitemattribute a  (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
               Recheck Cond: ((attributeid)::text = 'display-album'::text)
               ->  Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
                     Index Cond: ((attributeid)::text = 'display-album'::text)
   ->  Sort  (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
         Sort Key: b.orderid
         Sort Method:  quicksort  Memory: 76kB
         ->  Bitmap Heap Scan on orderitem b  (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
               Recheck Cond: ((productid)::text = 'ModernBook'::text)
               ->  Bitmap Index Scan on id_orderitem_productid  (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
                     Index Cond: ((productid)::text = 'ModernBook'::text)
 Total runtime: 842.134 ms
(17 rows)

Tente ler por si mesmo e ver se faz sentido.

O que eu li é que o banco de dados primeiro varre o índice id_orderitem_productid, usando isso para encontrar as linhas que quer de orderitem, em seguida, classifica esse conjunto de dados usando um quicksort (do tipo usado mudará se os dados não cabe na RAM), em seguida, define isso de lado.

Em seguida, ele verifica orditematt_attributeid_idx para encontrar as linhas que quer de orderitemattribute e em seguida, classifica esse conjunto de dados usando um quicksort.

Em seguida, leva os dois conjuntos de dados e mescla-los. (Uma união de combinação é uma espécie de "zipar" operação onde anda os dois ordenados conjuntos de dados em paralelo, emitindo a linha se juntou quando eles combinam.)

Como eu disse, você trabalha com o plano parte interna a parte exterior, de baixo para cima.

Não é uma ferramenta auxiliar on-line disponíveis também, Depesz , que irá destacar onde as peças caras da análise resultados são.

também tem um, aqui está a mesmos resultados , que me tornar mais claro onde o problema é.

PgAdmin irá mostrar-lhe uma representação gráfica do plano de explicar. Mudança e para trás entre os dois pode realmente ajudar você a entender o que significa a representação de texto. No entanto, se você só quer saber o que está acontecendo todo, você pode ser capaz de simplesmente usar sempre a GUI.

do PostgreSQL documentação oficial fornece um interessante, explicação completa sobre como entender explicar de saída .

Se você instalar pgadmin, há um botão Explique que, bem como dar a saída de texto desenha diagramas do que está acontecendo, mostrando os filtros, os tipos e fusões sub-conjunto que eu acho realmente útil para ver o que está acontecendo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top