Sur un tableau avec les colonnes a, b, c, d, e, f, g, h, i, j, k j'obtiens:
select * from misty order by a limit 25;
Time: 302.068 ms
Et:
select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;
Time: 1258.451 ms
Existe-t-il un moyen de rendre la sélection par colonne aussi rapide?
Mise à jour:
Aucun index sur une table, nouvellement créé
Voici le EXPLAIN ANALYZE, ne semble pas trop utile:
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)
Et:
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)
postgresql
postgresql-9.2
Evgeny
la source
la source
select *
cas et environ 2,2 s pour la sélection avec des colonnes répertoriées dans un ordre différent .select *
.Réponses:
Cela a été publié sur la liste de diffusion pgsql-hackers et j'ai essayé d'y répondre brièvement. Il semble que si la liste cible (colonnes spécifiées) correspond exactement au descripteur de tuple de la relation, c'est-à-dire à la fois en nombre de colonnes et dans l'ordre, l'analyse sous-jacente peut renvoyer un tuple directement consommable par le nœud de tri englobant. D'un autre côté, si la liste cible ne correspond pas (dans l'ordre ou le nombre de colonnes spécifiées), l'analyse renvoie une forme de tuples qui nécessite l'étape de préparation des données de Sort pour effectuer un travail supplémentaire (conversion d'un format de tuple interne en le format directement consommable par le code de tri).
Soit dit en passant, «*» est transformé en interne en une liste qui correspond (intuitivement) au descripteur de tuple de la relation.
EDIT: Si vous regardez les temps réels de votre dernier EXPLAIN ANALYZE Seq Scan, vous pouvez voir que c'est plus que les anciens. Cela s'est produit parce que l'analyse a effectué une étape supplémentaire de projection (c'est-à-dire la conversion du tuple de segment de mémoire en un format de valeurs internes [], nulls []). Et parce que cela s'est produit, le nœud de tri supérieur a dû faire un travail supplémentaire dans son initialisation des données, celle de la reconvertir au format de tuple que l'étape de tri réelle comprend. Cela ressort clairement du coût de démarrage du tri. Cela ne se produit pas dans le premier cas. Autrement dit, à la fois l'analyse renvoie le tuple tel quel et l'étape d'initialisation du tri le copie simplement.
la source