Por que SELECT * é muito mais rápido que selecionar todas as colunas (em uma ordem diferente) pelo nome?

12

Em uma tabela com colunas a, b, c, d, e, f, g, h, i, j, k, recebo:

select * from misty order by a limit 25;
Time: 302.068 ms

E:

select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;
Time: 1258.451 ms

Existe uma maneira de fazer a seleção por coluna o mais rápido?

Atualizar:

Nenhum índice em uma tabela, um recém-criado

Aqui está o EXPLAIN ANALYZE, não parece muito útil:

explain analyze select * from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=404.958..404.971 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=404.957..404.963 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.013..170.945 rows=694686 loops=1)
Total runtime: 405.019 ms
(6 rows)

E:

explain analyze select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=1371.735..1371.745 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=1371.733..1371.736 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.015..516.355 rows=694686 loops=1)
Total runtime: 1371.797 ms
(6 rows)
Evgeny
fonte
A coluna é indexada? Você pode postar explicar analisar?
user_0 25/05
1
Você precisa ter cuidado ao fazer duas seleções consecutivas e comparar os horários. Os dados no cache na segunda consulta podem explicar a diferença nos horários.
Walter Mitty 25/05
1
Também estou vendo diferenças, embora não tão pronunciadas. Minha tabela possui linhas = 514431 de largura = 215 e recebo aproximadamente 1,5s para o select *caso e aproximadamente 2,2s para o select com colunas listadas em uma ordem diferente .
Colin 'Hart
Se eu listar todas as colunas na mesma ordem que a definida na tabela, recebo aproximadamente os mesmos horários que eu select *.
Colin 'Hart
2
O título é enganoso. A questão é realmente por que a duração de uma classificação depende da ordem das colunas de saída.
Daniel Vérité 25/05

Respostas:

12

Isso foi postado na lista de discussão pgsql-hackers e tentei responder brevemente. Parece que se a lista de destino (colunas especificadas) corresponder exatamente ao descritor de tupla da relação, ou seja, tanto em número de colunas quanto em ordem, a varredura subjacente poderá retornar uma tupla que seja diretamente consumível pelo nó de Classificação envolvente. Por outro lado, se a lista de destinos não corresponder (na ordem ou no número de colunas especificadas), a varredura retornará um formulário das tuplas que requerem a etapa de preparação de dados de Sort para executar um trabalho extra (converter de um formato interno de tupla para o formato consumível diretamente pelo código de classificação).

A propósito, '*' é transformado internamente em uma lista que (intuitivamente) corresponde ao descritor de tuplas da relação.

EDIT: Se você olhar para os tempos atuais do Seq Scan do EXPLAIN ANALYZE, poderá ver que é mais do que o anterior. Isso aconteceu porque a varredura executou uma etapa adicional de projeção (ou seja, converter a tupla de heap em um formato interno de valores [], nulos []). E como isso aconteceu, o nó Classificação superior teve que fazer um trabalho extra em sua inicialização de dados, convertendo-o novamente no formato de tupla que a etapa de classificação real compreende. Isso é evidente pelo custo de inicialização do Sort. Isso não acontece no primeiro caso. Ou seja, a varredura retorna a tupla como está e a etapa de inicialização da classificação simplesmente a copia.

amitlan
fonte
@ Colin'tHart, espero que faça sentido.
Amitlan
Sim. Eu esperava que fosse possível pular essa etapa ou abreviá-la usando alguns "shuffling de ponteiros", mas essa é uma discussão para pgsql-hackers.
Colin 't Hart
Pode haver algumas melhorias no horizonte com o recente renascimento do trabalho de ordenação de colunas lógicas.
Amitlan
Eu já estava pensando sobre isso e espero que sim!
Colin 'Hart
Caro senhor, se eu precisar apenas de algumas colunas em vez de todas, o que será mais rápido? selecione * ou selecione algumas_de_colunas? Muito obrigado.
precisa saber é