Première question : pourquoi on bosse avec JSONB en fait ? JSONB te permet de stocker des données au format JSON, ce qui donne une structure super flexible. C’est super pratique quand tes données sont complexes et imbriquées (genre des profils utilisateurs avec une liste d’adresses ou de paramètres). Contrairement au simple JSON, JSONB stocke les données en binaire, ce qui rend les recherches et les filtres beaucoup plus rapides.
Mais sans index, chercher dans du JSONB peut être super lent, surtout si ta table a des milliers ou des millions de lignes. Imagine, t’as une table avec des infos utilisateurs, où tu stockes les paramètres de chaque utilisateur en JSONB. Essayer de trouver tous les utilisateurs avec une certaine valeur dans ces paramètres sans index — c’est un truc qui bouffe plein de ressources. Et c’est là que nos index débarquent !
Indexation JSONB : points importants
Pour bosser avec JSONB, PostgreSQL gère l’indexation de deux façons principales :
- GIN (Generalized Inverted Index) — pour chercher dans les clés et valeurs à l’intérieur du
JSONB. - BTREE — pour la recherche et le tri plus simples.
Chacun a ses particularités. On va voir ça plus en détail.
Index GIN pour JSONB
GIN, c’est un index puissant qui marche avec les tableaux, les textes, et aussi les données JSONB. Il "décompose" le contenu de l’objet JSONB en clés et valeurs séparées, et crée une structure spéciale pour chercher tout ça super vite.
Avantages de GIN pour JSONB :
- Tu peux chercher à la fois par clé et par valeur.
- Ça marche avec les structures imbriquées.
- Ça accélère les opérations avec les opérateurs
@>,?,?|,?&(filtrage des clés et valeurs).
Imaginons qu’on a une table users, où la colonne settings contient les paramètres utilisateurs au format JSONB. Exemple de données :
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
settings JSONB
);
INSERT INTO users (name, settings) VALUES
('Alice', '{"theme": "sombre", "notifications": {"email": true, "sms": false}}'),
('Bob', '{"theme": "clair", "notifications": {"email": false, "sms": true}}'),
('Charlie', '{"theme": "sombre", "notifications": {"email": true, "sms": true}}');
Maintenant, on veut trouver rapidement tous les utilisateurs avec le thème sombre (theme: sombre). D’abord, on crée l’index :
CREATE INDEX idx_users_settings_gin ON users USING GIN (settings);
Ensuite, fais une requête avec l’opérateur @> (recherche par valeur) :
SELECT name
FROM users
WHERE settings @> '{"theme": "sombre"}';
Maintenant PostgreSQL utilise l’index GIN pour la recherche, et la requête va beaucoup plus vite.
Comment ça marche ? Quand tu crées un index GIN sur une colonne JSONB, PostgreSQL construit un index "inversé", c’est-à-dire qu’il crée des entrées séparées pour toutes les clés et valeurs du JSON. Par exemple, à partir de l’objet :
{"theme": "sombre", "notifications": {"email": true, "sms": false}}
il va indexer les clés theme, notifications.email, notifications.sms et leurs valeurs. Ça rend la recherche sur chaque élément beaucoup plus rapide.
Index BTREE pour JSONB
BTREE, c’est l’index classique. Tu l’utilises si tu veux comparer des objets JSONB en entier ou faire du tri. Mais, contrairement à GIN, BTREE ne décompose pas le contenu de l’objet JSON.
Avantages de BTREE pour JSONB :
- Parfait pour les opérations de tri et de comparaison d’objets.
- Plus rapide si tu utilises
JSONBcomme un "bloc" (genre tu le compares à un autre objet ou tu cherches les lignes oùJSONBest égal à une valeur donnée).
Voici un exemple d’utilisation d’un index BTREE. Supposons que dans la table users tu veux souvent comparer la colonne settings à un objet précis :
{"theme": "sombre", "notifications": {"email": true, "sms": false}}
D’abord, crée l’index :
CREATE INDEX idx_users_settings_btree ON users USING BTREE (settings);
Maintenant tu peux faire des requêtes de comparaison d’objets :
SELECT name
FROM users
WHERE settings = '{"theme": "sombre", "notifications": {"email": true, "sms": false}}';
Cette requête va utiliser l’index BTREE pour aller plus vite.
Comparaison GIN et BTREE
| Caractéristique | GIN |
BTREE |
|---|---|---|
Décomposition de l’objet JSONB |
Oui, décompose en clés et valeurs | Non, compare l’objet entier |
| Recherche dans les structures imbriquées | Oui | Non |
| Tri | Non | Oui |
| Taille de l’index | Plus grande | Plus petite |
| Opérateurs supportés | @>, ?, ?|, ?& |
=, <, > |
Donc, GIN est top pour les requêtes complexes, alors que BTREE est utile quand tu veux comparer des objets entiers ou faire du tri.
Quel index choisir ?
- Si tu veux chercher par clé ou valeur à l’intérieur du
JSONB, prendsGIN. - Si tu veux comparer ou trier des objets
JSONBentiers,BTREEest mieux.
Mais n’oublie pas, tu peux combiner ces index ! Par exemple, tu peux créer à la fois un index GIN et un BTREE sur le même champ si ta table a besoin des deux types de requêtes.
Erreurs classiques lors de l’indexation JSONB
Créer des index inutiles : ça ne sert pas toujours d’indexer chaque champ JSONB. Les index prennent de la place et peuvent ralentir les insertions et mises à jour.
Indexer des opérateurs rarement utilisés : n’indexe pas un champ juste parce que ça te semble "bien". Analyse tes requêtes et indexe seulement là où ça accélère vraiment les opérations.
Ignorer les particularités de GIN : GIN peut prendre plus de temps à créer qu’un BTREE. Faut y penser quand tu indexes de grosses tables.
Application pratique
Bosser avec JSONB est super utile dans les projets réels où les données sont flexibles et dynamiques. Par exemple :
- Applis web avec des paramètres utilisateurs.
- Stockage de logs qui ont des champs différents selon l’événement.
- Cache de données au format JSON.
L’indexation de ces données avec GIN et BTREE aide vraiment à booster les perfs des requêtes. Par exemple, en entretien, tu peux montrer comment t’as accéléré un système en ajoutant de l’indexation pour des structures de données complexes.
La doc officielle PostgreSQL sur les index JSON est dispo ici. N’hésite pas à y jeter un œil pour des précisions et des exemples.
GO TO FULL VERSION