Pourquoi l'analyse séquentielle peut être beaucoup plus rapide que l'analyse d'index et l'analyse d'index uniquement dans cette requête simple ?

dba.stackexchange https://dba.stackexchange.com/questions/108129

Question

j'utilise PostgreSQL 9.4.4.J'ai une requête comme celle-ci :

 SELECT COUNT(*) FROM A,B WHERE A.a = B.b

a et b sont les clés primaires des tables A et B, il y a donc des index B sur a & b

Par défaut, PostgreSQL utilisera seq-scan sur AB et utilisera la jointure par hachage, je le force à effectuer l'analyse d'index et l'analyse d'index uniquement.

Le résultat a montré que l'analyse séquentielle est beaucoup plus rapide que les deux autres, qu'il faut plus de temps pour effectuer l'analyse complète sur a, b pour l'analyse d'index et l'analyse d'index uniquement.

EXPLAIN ANALYZE SELECT COUNT(*) FROM journal,paper WHERE journal.paper_id = paper.paper_id;

enter image description here

Quelqu'un peut-il l'expliquer ?

Merci beaucoup!

Était-ce utile?

La solution 2

Je connais la raison maintenant.

Je dois passer l'aspirateur sur les tables avant d'utiliser l'analyse d'index uniquement, sinon, si un nombre suffisamment élevé de pages de tas ont été modifiées depuis le dernier aspirateur, le planificateur ne choisira pas d'utiliser l'analyse d'index uniquement.Lorsque seule une petite quantité de pages a été modifiée, une analyse d'index uniquement peut avoir lieu, ce qui implique alors des récupérations de tas.

Si je le force à utiliser l'analyse d'index uniquement, il récupérera les données de la table pour chaque tuple analysé, ce qui peut entraîner des coûts importants.

Autres conseils

C’est une requête assez courante (pardonnez le jeu de mots !:-) ) de personnes exécutant des requêtes qui effectuent des analyses de table complètes (FTS), lorsque l'affiche estime que le système devrait utiliser le ou les index.

En gros, cela se résume à l'explication donnée ici.Si les tables sont si petites, l'optimiseur dira que "cela ne vaut pas la peine d'aller dans l'index, de faire une recherche puis de récupérer les données, à la place, je vais simplement absorber toutes les données et choisir ce dont j'ai besoin". ", c'est à dire.effectuer un FTS.

[EDIT en réponse au commentaire de @txsing]

Pour un MVCC (contrôle de concurrence multiversion), vous devez parcourir chaque enregistrement pour un nombre à un moment donné - c'est pourquoi, par exemple, un COUNT(*) est beaucoup plus cher pour InnoDB de MySQL que pour MyISAM.

Une excellente explication (pour PostgreSQL) est disponible ici.Le gars qui a écrit ce post est un "contributeur majeur" à PostgreSQL (merci à @dezso de m'avoir conduit à ce message).

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top