La version 9.5 de PostgreSQL sortie en Janvier 2016 propose un nouveau type d’index : les Index BRIN pour Bloc Range INdex. Ces derniers sont recommandés pour les tables volumineuses et corrélées avec leur emplacement. J’ai décidé de consacrer une série d’article sur ces index :

Pour information, je serai présent au PGDay France à Lille le mardi 31 mai pour présenter cet index. Il y aura également plein d’autres conférences intéressantes!

Dans ce troisième article nous verrons pourquoi la corrélation des données avec leur emplacement est importante pour les index BRIN.

Données corrélées

Ces premiers exemples étaient volontairement simples voire simplistes afin de faciliter la compréhension. Les enregistrements avaient une particularité importante : les valeurs étaient croissantes.

Ce qui signifie qu’il y a une forte corrélation entre les enregistrements et leur emplacement.

Pour information, le moteur stocke des statistiques sur les tables afin de choisir le meilleur plan d’exécution. Lançons un ANALYSE sur notre table brin_demo et consultons la vue pg_stats, notamment la colonne « correlation » :

Essayons avec des données aléatoires :

=> La vue pg_stats nous indique que les données ne sont pas corrélées avec leur emplacement.

Que contient notre index?

L’index nous indique que tous les blocs contiennent des valeurs comprises entre 1 et 90.

Que donne une recherche des valeurs comprises entre 10 et 20?

=> Le moteur lit l’intégralité de la table ainsi que 2 blocs d’index.

Il est légitime de se demander quel est l’intérêt d’utiliser l’index si on sait que les données ne sont pas corrélées. Et qu’au final le moteur sera contraint de lire toute la table.

Allons faire un tour dans le code source. Plus précisément à la ligne 7568 du fichier src/backend/utils/adt/selfuncs.c :

On peut voir « *indexCorrelation = 1; ». En réalité le moteur ignore la corrélation… pour le moment. Une discussion est en cours pour prendre en compte la corrélation dans le coût de l’index : http://www.postgresql.org/message-id/20151116135239.GV614468@alvherre.pgsql

Trions notre table en utilisant l’ordre CLUSTER et un index b-tree :

Vérifions la corrélation :

Rejouons notre requête :

Cette fois le moteur a lu moins de blocs, regardons ce que contient notre index :

Cette fois le moteur savait qu’il n’avait à parcourir que les blocs de 48 à 96.

Share

Ecrire un commentaire

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 

requis