Partager via


Meilleures pratiques d’indexation dans Azure DocumentDB

Les champs interrogeables doivent toujours avoir des index créés

Les opérations de lecture basées sur les prédicats et les agrégats consultent l’index pour les filtres correspondants. En l’absence d’index, le moteur de base de données effectue une analyse de document pour récupérer les documents correspondants. Les analyses sont toujours coûteuses et sont progressivement plus coûteuses à mesure que le volume de données d’une collection augmente. Pour optimiser les performances des requêtes, les index doivent toujours être créés pour tous les champs interrogeables.

Éviter les index inutiles et l’indexation de tous les champs par défaut

Les index doivent être créés uniquement pour les champs interrogeables. L’indexation par caractères génériques doit être utilisée uniquement lorsque les modèles de requête sont imprévisibles où n’importe quel champ de la structure de document peut faire partie des filtres de requête.

Conseil / Astuce

Azure DocumentDB indexe uniquement le champ _id par défaut. Tous les autres champs ne sont pas indexés par défaut. Les champs à indexer doivent être planifiés à l’avance pour optimiser les performances des requêtes, tout en réduisant l’impact sur les écritures provenant de l’indexation de trop de champs.

Lorsqu’un nouveau document est inséré pour la première fois ou qu’un document existant est mis à jour ou supprimé, chacun des champs spécifiés dans l’index est également mis à jour. Si la stratégie d’indexation contient un grand nombre de champs (ou tous les champs du document), d’autres ressources sont consommées par le serveur lors de la mise à jour des index correspondants. Lors de l’exécution à grande échelle, seuls les champs pouvant être interrogés doivent être indexés, tandis que tous les champs restants non utilisés dans les prédicats de requête doivent rester exclus de l’index.

Stratégie d’indexation pour une ingestion de données efficace

Pour les migrations de charges de travail volumineuses dans Azure DocumentDB, il est recommandé de créer des index après la charge de données pour une exécution efficace. Cela réduit considérablement la surcharge d’écriture, réduit la consommation des ressources et accélère les performances d’ingestion des données. La maintenance des index pendant l’ingestion en bloc peut ralentir les insertions, car chaque opération d’écriture doit mettre à jour tous les index applicables.

Pour plusieurs index créés sur des données historiques, émettez des commandes createIndex non bloquantes pour chaque champ

Il n’est pas toujours possible de planifier tous les modèles de requête à l’avance, en particulier à mesure que les exigences de l’application évoluent. La modification des besoins de l’application nécessite inévitablement l’ajout de champs à l’index sur un cluster avec une grande quantité de données historiques.

Dans de tels scénarios, chaque commande createIndex doit être émise de manière asynchrone sans attendre une réponse du serveur.

Note

Par défaut, Azure DocumentDB répond à une opération createIndex uniquement une fois que l’index est entièrement basé sur les données historiques. Selon la taille du cluster et le volume de données ingérées, cela peut prendre du temps et apparaître comme si le serveur ne répond pas à la commande createIndex.

Si les commandes createIndex sont émises via l’interpréteur de commandes Mongo, utilisez Ctrl + C pour interrompre la commande pour arrêter d’attendre une réponse et émettre le jeu d’opérations suivant.

Note

L’utilisation de Ctrl + C pour interrompre la commande createIndex une fois qu’elle a été émise n’arrête pas l’opération de génération d’index sur le serveur. Il empêche simplement l’interpréteur de commandes d’attendre une réponse du serveur, tandis que le serveur continue de générer de façon asynchrone l’index sur les documents existants.

Créer des index composés pour les requêtes avec des prédicats sur plusieurs champs

Les index composés doivent être utilisés dans les scénarios suivants :

  • Requêtes avec des filtres sur plusieurs champs
  • Requêtes avec des filtres sur plusieurs champs et avec un ou plusieurs champs triés par ordre croissant ou décroissant

Considérez le document suivant dans la base de données « cosmosworks » et la collection « employee »

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

Considérez la requête suivante pour rechercher tous les employés portant le nom « Smith » avec l’organisation pendant plus de cinq ans :

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

Un index composé sur « lastName » et « timeInOrgInYears » optimise cette requête :

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

Suivre l’état d’une opération createIndex

Lorsque des index sont ajoutés et que les données historiques doivent être indexées, la progression de l’opération de génération d’index peut être suivie à l’aide de db.currentOp().

Considérez cet exemple pour suivre la progression de l’indexation sur la base de données « cosmosworks ».

use cosmicworks;
db.currentOp()

Lorsqu’une opération createIndex est en cours, la réponse ressemble à ceci :

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

Activer les clés d’index volumineuses par défaut

Même si les documents ne contiennent pas de clés qui ont un grand nombre de caractères ou si les documents ne contiennent pas plusieurs niveaux d’imbrication, la spécification de clés d’index volumineuses garantit que ces scénarios sont couverts. Maintenant, la clé d’index volumineuse est le comportement par défaut du moteur.

Considérez cet exemple pour activer les clés d’index volumineuses sur la collection « large_index_coll » dans la base de données « cosmosworks ».

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

Priorisation de la construction d'index par rapport aux nouvelles opérations d'écriture en utilisant l'option de blocage.

Pour les scénarios dans lesquels l’index doit être créé avant le chargement des données, l’option de blocage doit être utilisée pour bloquer les écritures entrantes jusqu’à la fin de la génération d’index.

Le paramètre { "blocking": true } est utile dans les utilitaires de migration où les index sont créés sur des collections vides avant le début des écritures de données.

Prenons un exemple de l’option bloquante pour la création d’index sur la collection « employee » dans la base de données « cosmiqueworks » :

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

Consultez l’indexation de texte, ce qui permet une recherche efficace et l’interrogation de données textuelles.

Étape suivante