Comprendre «analyse de tas de bitmap» et «analyse d’index bitmap»


36

Je vais essayer d'expliquer mes malentendus à l'aide de l'exemple suivant.

Je ne comprenais pas les fondamentaux du Bitmap Heap Scan Node. Considérons la requête dont SELECT customerid, username FROM customers WHERE customerid < 1000 AND username <'user100';le plan est le suivant:

Bitmap Heap Scan on customers  (cost=25.76..61.62 rows=10 width=13) (actual time=0.077..0.077 rows=2 loops=1)
  Recheck Cond: (((username)::text < 'user100'::text) AND (customerid < 1000))
  ->  BitmapAnd  (cost=25.76..25.76 rows=10 width=0) (actual time=0.073..0.073 rows=0 loops=1)
        ->  Bitmap Index Scan on ix_cust_username  (cost=0.00..5.75 rows=200 width=0) (actual time=0.006..0.006 rows=2 loops=1)
              Index Cond: ((username)::text < 'user100'::text)
        ->  Bitmap Index Scan on customers_pkey  (cost=0.00..19.75 rows=1000 width=0) (actual time=0.065..0.065 rows=999 loops=1)
              Index Cond: (customerid < 1000)

Ma compréhension de ce noeud :

Comme expliqué ici , les bitmap heap scanblocs de table de lecture sont classés dans un ordre séquentiel, de sorte qu'ils ne génèrent pas de surcharge liée à un accès aléatoire à une table Index Scan.

Une fois Index Scancela fait, PostgreSQL ne sait pas comment extraire les lignes de manière optimale, pour éviter les inutiles heap blocks reads(ou hitss’il existe un cache actif). Donc, pour le comprendre, il génère la structure ( Bitmap Index Scan) appelée, bitmapqui dans mon cas est générée en générant deux bitmaps des index et en effectuant BITWISE AND. Comme le bitmap a été généré, il peut maintenant lire la table de manière optimale dans un ordre séquentiel, en évitant d’être inutile heap I/O-operations.

C'est l'endroit où beaucoup de questions viennent.

QUESTION: Nous avons juste un bitmap. Comment PostgreSQL sait-il par un bitmap quoi que ce soit sur l'ordre physique des lignes? Ou génère le bitmap de sorte que n'importe quel élément de celui-ci puisse être mappé au pointeur sur une page facilement? Si c'est le cas, cela explique tout, mais je ne fais que deviner.

Alors, pouvons-nous simplement dire que cela bitmap heap scan -> bitmap index scanressemble à une analyse séquentielle mais uniquement à la partie appropriée de la table?


J'ai écrit une explication de certaines de ces choses
Craig Ringer

@CraigRinger Il semble que je n'ai pas expliqué correctement ce que je n'ai pas compris. Bien sûr, comme vous l'avez expliqué, nous avons une image par laquelle PostgreSQL lit la table séquentiellement. Je ne comprends pas comment il peut comprendre le bloc réel désigné par un bitmap spécifique, par exemple 001001010101011010101. Ou alors, cela n’a pas d’importance et tout ce que nous avons à savoir, c’est que nous pouvons trouver un bloc en mode bitmap assez rapidement ...?
St.Antario

Ah, vous ne comprenez peut-être pas ce que "bitmap" signifie ici. Me laisser suivre dans une édition.
Craig Ringer

@CraigRinger Peut-être que j'ai pris la définition à partir de .
St.Antario

Réponses:


52

Comment PostgreSQL sait-il par un bitmap quoi que ce soit sur l'ordre physique des lignes?

Le bitmap est un bit par page de tas. L'analyse d'index bitmap définit les bits en fonction de l'adresse de page de tas vers laquelle l'entrée d'index pointe.

Ainsi, lorsqu’il effectue l’analyse de tas de bitmap, il effectue simplement un balayage de table linéaire, en lisant l’image bitmap pour voir si elle doit s’embêter avec une page particulière ou la rechercher.

Ou génère le bitmap de sorte que n'importe quel élément de celui-ci puisse être mappé au pointeur sur une page facilement?

Non, le bitmap correspond 1: 1 aux pages de tas.

J'ai écrit un peu plus à ce sujet ici .


OK, vous avez peut-être mal compris ce que "bitmap" signifie dans ce contexte.

Ce n'est pas une chaîne de bits, comme "101011", qui est créée pour chaque page de tas, ou chaque index lu, ou autre chose.

Le bitmap entier est un tableau à un seul bit , avec autant de bits qu'il y a de pages de tas dans la relation en cours d'analyse.

Un bitmap est créé lors de la première analyse d'index, en commençant par toutes les entrées 0 (false). Chaque fois qu'une entrée d'index correspondant à la condition de recherche est trouvée, l'adresse de segment pointée par cette entrée d'index est recherchée comme un décalage dans le bitmap et ce bit est défini sur 1 (true). Ainsi, plutôt que de rechercher directement la page de tas, l'analyse d'index bitmap recherche la position du bit correspondant dans le bitmap.

La deuxième analyse et les analyses ultérieures des index bitmap font la même chose avec les autres index et les conditions de recherche correspondantes.

Ensuite, chaque bitmap est ANDed ensemble. Le bitmap résultant a un bit pour chaque page de tas, où les bits ne sont vrais que s'ils le sont dans toutes les analyses d'index bitmap individuelles, c'est-à-dire que la condition de recherche correspond à chaque analyse d'index. Ce sont les seules pages de tas que nous devons prendre la peine de charger et d’examiner. Etant donné que chaque page de tas peut contenir plusieurs lignes, nous devons ensuite examiner chaque ligne pour voir si elle correspond à toutes les conditions - c'est le sens de la partie "re-vérifier cond".

Une chose cruciale à comprendre avec tout cela est que l'adresse de tuple dans une entrée d'index pointe vers la ligne ctid, qui est une combinaison du numéro de page de tas et du décalage dans la page de tas. Une analyse d'index bitmap ignore les décalages, car elle vérifie néanmoins la totalité de la page et définit le bit si une ligne de cette page correspond à la condition.


Exemple graphique

Heap, one square = one page:
+---------------------------------------------+
|c____u_____X___u___X_________u___cXcc______u_|
+---------------------------------------------+
Rows marked c match customers pkey condition.
Rows marked u match username condition.
Rows marked X match both conditions.


Bitmap scan from customers_pkey:
+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
+---------------------------------------------+
One bit per heap page, in the same order as the heap
Bits 1 when condition matches, 0 if not

Bitmap scan from ix_cust_username:
+---------------------------------------------+
|000001000001000100010000000001000010000000010| bitmap 2
+---------------------------------------------+

Une fois que les bitmaps sont créés, AND est exécuté sur les bits:

+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
|000001000001000100010000000001000010000000010| bitmap 2
 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|000000000001000000010000000000000010000000000| Combined bitmap
+-----------+-------+--------------+----------+
            |       |              |
            v       v              v
Used to scan the heap only for matching pages:
+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+

L’analyse de tas bitmap cherche ensuite au début de chaque page et lit la page:

+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+
seek------->^seek-->^seek--------->^
            |       |              |
            ------------------------
            only these pages read

et chaque page lue est ensuite vérifiée par rapport à la condition car il peut y avoir> 1 ligne par page et toutes ne correspondent pas nécessairement à la condition.


Ah, voilà ce qu'ils voulaient dire par peuplant le bitmap.
St.Antario

@ St.Antario J'ai ajouté des graphiques pour expliquer
Craig Ringer

Permettez-moi de clarifier une dernière chose à propos de bitmap-scan. Vous avez dit que nous avons un bitmap 1: 1 en tas de pages et que nous pouvons déterminer une page de tas par un index bit dans le bitmap. Etant donné que la relation peut contenir des pages sur un disque dans un ordre non séquentiel (non clusterisé), la manière dont nous pouvons déterminer l'adresse d'une page par simple décalage dans un bitmap. Je présume que le planificateur sait comment calculer une adresse de page par décalage pour une relation donnée . Est-ce vrai?
St.Antario

1
Nous devons donc mettre toutes les pages qui sont sur un lecteur. De plus, les données de la relation peuvent être réparties sur deux disques ou plus (il est donc difficile d'imaginer un ordre linéaire des pages de la relation ). Il est donc difficile de déterminer le décalage réel de la page suivante. Parce que je crois que par "décalage", vous entendiez le décalage physique réel correspondant à une position physique sur un lecteur.
St.Antario

2
PostgreSQL ne se soucie pas du tout des lecteurs. Il ne s'intéresse qu'aux fichiers du système de fichiers . Le fichier logique de la relation est linéaire et contigu, et c'est ce que le bitmap est terminé. (Le fichier peut contenir plusieurs étendues, mais elles sont traitées comme si elles étaient ajoutées en permanence, et le bitmap les recouvrait toutes). Vous regardez au mauvais niveau d'abstraction. (En passant, le bitmap dans l'analyse d'un index bitmap n'est pas non plus calculé par le planificateur, il fait partie de la méthode d'accès à un index btree et est davantage lié à l'exécuteur qu'à le planificateur).
Craig Ringer

3

Veuillez consulter mon article de blog https://rajeevrastogi.blogspot.in/2018/02/bitmap-scan-in-postgresql.html?showComment=1518410565792#c4647352762092142586 pour obtenir une description détaillée de l'analyse bitmap dans PostgreSQL.

Vue d'ensemble rapide des fonctionnalités de l'analyse bitmap:

  1. Analyse Bitmap Heap demander un tuple à partir de Bitmap Index Scan.

  2. Analyse d'index bitmap Analyser l'index conformément à la condition presque de la même manière que dans l'analyse d'index normale. Mais au lieu de renvoyer un TID (composé de la page no et du décalage dans celui-ci) correspondant aux données de tas, il ajoute ces TID dans un bitmap. Pour une compréhension simple, vous pouvez considérer que cette image contient le hachage de toutes les pages (haché sur la base du numéro de page) et que chaque entrée de page contient un tableau de tous les décalages au sein de cette page.

  3. Ensuite, Bitmap Heap Scan lit le bitmap pour obtenir des données de tas correspondant au numéro de page et au décalage stockés. Ensuite, il vérifie la visibilité, la qualification, etc. et renvoie le tuple en fonction du résultat de toutes ces vérifications.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.