Aller au contenu

CouchDB : index et performances

Fenêtre de terminal
curl -sn -X POST "$COUCH/boutique/_index" -H 'Content-Type: application/json' \
-d '{"index":{"fields":["type","email"]},"name":"idx-type-email","type":"json"}' | jq .
curl -sn "$COUCH/boutique/_index" | jq '.indexes[] | {name, def}'
curl -sn -X DELETE "$COUCH/boutique/_index/_design/<ddoc>/json/idx-type-email"

Règles :

  • Un index sur ["type","email"] sert aux requêtes qui filtrent type, puis email (l’ordre des champs compte).
  • Les champs du tri doivent être dans l’index et dans le même ordre.
  • Un index partiel limite la taille :
Fenêtre de terminal
curl -sn -X POST "$COUCH/boutique/_index" -H 'Content-Type: application/json' -d '{
"index": { "fields": ["email"], "partial_filter_selector": { "type": "client" } },
"name": "idx-email-clients", "type": "json"
}'

Vérifier l’usage avec _explain (voir Requêtes) : l’index attendu doit apparaître.

Une vue est une fonction JavaScript map qui émet des couples clé/valeur, stockés dans un index trié par clé.

Fenêtre de terminal
curl -sn -X PUT "$COUCH/boutique/_design/stats" -H 'Content-Type: application/json' -d '{
"views": {
"par-client": {
"map": "function(doc) { if (doc.type === \"commande\") { emit(doc.client, doc.total); } }"
},
"total-par-client": {
"map": "function(doc) { if (doc.type === \"commande\") { emit(doc.client, doc.total); } }",
"reduce": "_sum"
}
}
}'
curl -sn "$COUCH/boutique/_design/stats/_view/par-client?key=\"client-2\"" | jq .
curl -sn "$COUCH/boutique/_design/stats/_view/total-par-client?group=true" | jq .rows
curl -sn "$COUCH/boutique/_design/stats/_view/total-par-client" | jq .rows # total général

Fonctions de réduction intégrées (à préférer au JavaScript, bien plus rapides) :

Réduction Calcul
_count Nombre de lignes
_sum Somme des valeurs numériques
_stats Somme, minimum, maximum, nombre, somme des carrés

Éviter de rendre la vue lourde : n’émettre que ce qui est nécessaire, ne pas émettre le document entier (utiliser include_docs=true à la lecture).

Fenêtre de terminal
curl -sn "$COUCH/_active_tasks" | jq '.[] | {type, database, progress, design_document}'

Types : indexer (construction d’une vue), database_compaction, view_compaction, replication.

CouchDB n’écrit qu’à la fin des fichiers : les anciennes révisions et les index s’accumulent. La compaction réécrit le fichier sans les données obsolètes.

Fenêtre de terminal
curl -sn -X POST "$COUCH/boutique/_compact" -H 'Content-Type: application/json'
curl -sn -X POST "$COUCH/boutique/_compact/stats" -H 'Content-Type: application/json' # vues d'un document de conception
curl -sn -X POST "$COUCH/boutique/_view_cleanup" -H 'Content-Type: application/json' # supprime les index orphelins
curl -sn "$COUCH/boutique" | jq '.sizes'

sizes.file (taille sur disque) bien supérieure à sizes.active (données utiles) indique qu’une compaction est utile.

La compaction automatique se règle dans /opt/couchdb/etc/local.d/ :

[compactions]
_default = [{db_fragmentation, "70%"}, {view_fragmentation, "60%"}, {from, "23:00"}, {to, "04:00"}]

Prévoir de l’espace disque libre (jusqu’à la taille de la base) pendant la compaction.

Pratique Raison
Lire par _id ou plage d’identifiants Chemin le plus rapide
Indexer chaque requête fréquente Évite le parcours complet
Paginer avec startkey ou signet, pas avec skip skip relit toutes les lignes ignorées
Limiter include_docs=true Chaque document lu coûte une lecture supplémentaire
Écrire en lot (_bulk_docs) Moins d’allers-retours
Garder les documents petits Réplication et index plus rapides
Fenêtre de terminal
curl -sn "$COUCH/_node/_local/_config/couchdb" | jq .
curl -sn -X PUT "$COUCH/_node/_local/_config/couchdb/max_dbs_open" -d '"500"'
curl -sn -X PUT "$COUCH/_node/_local/_config/chttpd/max_http_request_size" -d '"67108864"'

Après les modifications de fichier, sudo systemctl restart couchdb. Sur un serveur partagé avec d’autres services, limiter les ressources (voir systemd : durcissement) : l’Erlang de CouchDB utilise autant de processeurs que disponible.

Fenêtre de terminal
curl -sn "$COUCH/_node/_local/_stats/couchdb/open_databases" | jq .
curl -sn "$COUCH/_node/_local/_system" | jq '{uptime, memory, run_queue}'
df -h /opt/couchdb/data
sudo du -sh /opt/couchdb/data/shards

Surveiller l’espace disque en priorité : une partition pleine rend la base inutilisable.

Symptôme Piste
Première lecture d’une vue très longue Construction de l’index : _active_tasks
{"error":"timeout"} Requête trop longue : ajouter un index, réduire l’intervalle
Disque qui se remplit Compaction manquante, anciennes révisions, index orphelins (_view_cleanup)
Requête Mango lente _explain : index absent ou non utilisé
skip lent Paginer par signet ou startkey
{"error":"query_parse_error"} Syntaxe du sélecteur ou de la vue
La vue ne reflète pas les changements Index en cours de construction : réessayer, ou paramètre update=lazy désactivé

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune propre à la distribution. Les réglages (compaction, mémoire) dépendent du matériel et de la version de CouchDB.