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 scan
blocs 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 Scan
cela fait, PostgreSQL ne sait pas comment extraire les lignes de manière optimale, pour éviter les inutiles heap blocks reads
(ou hits
s’il existe un cache actif). Donc, pour le comprendre, il génère la structure ( Bitmap Index Scan
) appelée, bitmap
qui 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 scan
ressemble à une analyse séquentielle mais uniquement à la partie appropriée de la table?
la source
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 ...?Réponses:
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.
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
Une fois que les bitmaps sont créés, AND est exécuté sur les bits:
L’analyse de tas bitmap cherche ensuite au début de chaque page et lit la page:
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.
la source
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:
Analyse Bitmap Heap demander un tuple à partir de Bitmap Index Scan.
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.
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.
la source