PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Qu'est-ce que l'explication de PostgreSQL me dit exactement ?

La partie que j'ai toujours trouvée déroutante est le coût de démarrage par rapport au coût total. Je Google cela chaque fois que je l'oublie, ce qui me ramène ici, ce qui n'explique pas la différence, c'est pourquoi j'écris cette réponse. C'est ce que j'ai glané de Postgres EXPLAIN documentation, expliquée comme je la comprends.

Voici un exemple tiré d'une application qui gère un forum :

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)

Voici l'explication graphique de PgAdmin :

(Lorsque vous utilisez PgAdmin, vous pouvez pointer votre souris sur un composant pour lire les détails du coût.)

Le coût est représenté sous la forme d'un tuple, par ex. le coût de la LIMIT est cost=0.00..3.39 et le coût de la numérisation séquentielle de post est cost=0.00..15629.12 . Le premier nombre du tuple est le coût de démarrage et le deuxième chiffre est le coût total . Parce que j'ai utilisé EXPLAIN et non EXPLAIN ANALYZE , ces coûts sont des estimations et non des mesures réelles.

  • Coût de démarrage est un concept délicat. Il ne représente pas seulement le temps avant que ce composant démarre . Il représente le temps entre le moment où le composant commence à s'exécuter (lecture des données) et le moment où le composant affiche sa première ligne .
  • Coût total est le temps d'exécution complet du composant, depuis le moment où il commence à lire les données jusqu'au moment où il finit d'écrire sa sortie.

Comme complication, les coûts de chaque nœud "parent" incluent les coûts de ses nœuds enfants. Dans la représentation textuelle, l'arbre est représenté par une indentation, par ex. LIMIT est un nœud parent et Seq Scan est son enfant. Dans la représentation PgAdmin, les flèches pointent de l'enfant vers le parent - la direction du flux de données - ce qui peut être contre-intuitif si vous êtes familier avec la théorie des graphes.

La documentation indique que les coûts incluent tous les nœuds enfants, mais notez que le coût total du parent 3.39 est beaucoup plus petit que le coût total de son enfant 15629.12 . Le coût total n'est pas inclus, car un composant tel que LIMIT n'a pas besoin de traiter l'intégralité de son entrée. Voir le EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; exemple dans Postgres EXPLAIN documents.

Dans l'exemple ci-dessus, le temps de démarrage est nul pour les deux composants, car aucun des composants n'a besoin d'effectuer de traitement avant de commencer à écrire des lignes :un parcours séquentiel lit la première ligne de la table et l'émet. La LIMIT lit sa première ligne puis l'émet.

Quand un composant doit-il effectuer beaucoup de traitement avant de pouvoir commencer à générer des lignes ? Il y a beaucoup de raisons possibles, mais regardons un exemple clair. Voici la même requête d'avant mais contenant maintenant un ORDER BY clause :

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)

Et graphiquement :

Encore une fois, le scan séquentiel sur post n'a pas de coût de démarrage :il commence à produire des lignes immédiatement. Mais le tri a un coût de démarrage important 23283.24 car il doit trier toute la table avant de pouvoir sortir ne serait-ce qu'une seule ligne . Le coût total du tri 23859.27 n'est que légèrement supérieur au coût de démarrage, reflétant le fait qu'une fois que l'ensemble de données a été trié, les données triées peuvent être émises très rapidement.

Notez que le temps de démarrage de LIMIT 23283.24 est exactement égal au temps de démarrage du tri. Ce n'est pas parce que LIMIT lui-même a un temps de démarrage élevé. Il n'a en fait aucun temps de démarrage par lui-même, mais EXPLAIN cumule tous les frais liés aux enfants pour chaque parent, de sorte que LIMIT le temps de démarrage inclut la somme des temps de démarrage de ses enfants.

Ce cumul des coûts peut compliquer la compréhension du coût d'exécution de chaque composant individuel. Par exemple, notre LIMIT n'a aucun temps de démarrage, mais ce n'est pas évident à première vue. Pour cette raison, plusieurs autres personnes se sont liées à expliquer.depesz.com, un outil créé par Hubert Lubaczewski (alias depesz) qui aide à comprendre EXPLAIN en soustrayant, entre autres, les frais liés aux enfants des frais liés aux parents. Il mentionne d'autres complexités dans un court article de blog sur son outil.