Se rendre au contenu

Champ indexé dans Odoo : Un guide pratique pour les développeurs et les consultants

Comment fonctionne l'attribut d'index dans l'ORM Odoo, quand l'utiliser et ce que cela signifie pour les performances de votre base de données.
6 mars 2026 par
Champ indexé dans Odoo : Un guide pratique pour les développeurs et les consultants
Dasolo
| Aucun commentaire pour l'instant

Introduction


Si vous avez passé du temps à écrire ou à examiner des définitions de champs Odoo, vous êtes probablement tombé sur quelque chose comme index=True sur un champ. Cela semble petit, presque comme une réflexion après coup. Mais cet attribut unique peut faire une différence significative dans la rapidité avec laquelle votre instance Odoo répond lorsque les utilisateurs recherchent, filtrent ou naviguent dans de grands ensembles de données.


Ce guide explique ce qu'est réellement un champ indexé dans le contexte du modèle de données Odoo, comment cela affecte votre base de données et quand il est judicieux de l'utiliser dans votre propre travail de développement Odoo. Que vous construisiez un module personnalisé ou que vous examiniez une implémentation existante, comprendre ce concept vous aidera à prendre de meilleures décisions.

Qu'est-ce qu'un champ indexé dans Odoo


Dans l'ORM Odoo, un champ est déclaré indexé lorsque sa définition inclut index=True. Cela indique à Odoo de demander à PostgreSQL de créer un index B-arbre sur la colonne de base de données correspondante lorsque le module est installé ou mis à jour.


Voici un exemple simple d'une définition de champ Odoo en Python :

class SaleOrder(models.Model):
    _name = 'sale.order'

    reference = fields.Char(string='Référence', index=True)
    state = fields.Selection([...], index=True)
    partner_id = fields.Many2one('res.partner', index=True)

D'un point de vue interface utilisateur, il n'y a rien de visible concernant les champs indexés. Un utilisateur remplissant un formulaire ou parcourant une vue en liste n'a aucun moyen de savoir si un champ est indexé ou non. L'indexation est entièrement une préoccupation au niveau de la base de données.


Ce que cela affecte, c'est la vitesse. Lorsqu'un champ est indexé, PostgreSQL peut rechercher des enregistrements correspondants beaucoup plus rapidement, en particulier sur des tables contenant des milliers ou des millions de lignes. Sans index, la base de données doit scanner chaque ligne de la table pour trouver celles qui correspondent à vos critères de recherche. Avec un index, elle navigue dans une structure triée et trouve directement les résultats.


Quels types de champs Odoo prennent en charge index=True

La plupart des types de champs scalaires dans l'ORM Odoo prennent en charge l'attribut index :

  • Champs Char et Text
  • Champs Integer et Float
  • Champs Date et Datetime
  • Champs Selection
  • Champs Many2one (très souvent indexés)
  • Champs Boolean

Les champs relationnels comme One2many et Many2many n'ont pas de colonne directe à indexer de la même manière, donc l'attribut index n'est pas pertinent pour eux. Les champs calculés qui ne sont pas stockés ne peuvent également pas être indexés, car ils n'ont pas de colonne de base de données.

Comment fonctionne le champ


Lorsque Odoo initialise ou met à jour un module, il lit toutes les définitions de champs et synchronise le schéma de la base de données. Pour tout champ avec index=True, Odoo exécute une instruction SQL pour créer un index sur cette colonne dans PostgreSQL.


Par défaut, PostgreSQL crée un index B-arbre, qui est le type d'index standard et fonctionne bien pour les comparaisons d'égalité (=), les requêtes de plage (>, <, BETWEEN) et le tri. Cela couvre la grande majorité de ce qu'Odoo fait lors du filtrage des enregistrements dans les vues de liste ou lors du calcul des recherches basées sur un domaine.


Comment cela interagit avec l'ORM Odoo

L'ORM Odoo traduit les filtres de domaine Python en requêtes SQL. Lorsque vous écrivez un domaine comme [('state', '=', 'sale')], l'ORM génère quelque chose comme WHERE state = 'sale'. Si le champ state a un index, PostgreSQL l'utilise pour résoudre cette condition efficacement sans scanner toute la table.


Les champs Many2one sont un cas d'utilisation très courant. Dans le modèle de données d'Odoo, un champ comme partner_id sur un bon de commande stocke l'ID entier du partenaire associé. Lorsque vous ouvrez la liste des commandes filtrées par client, Odoo exécute une requête avec une condition WHERE partner_id = X. Avec un index sur partner_id, cette recherche est rapide même avec des centaines de milliers de commandes dans la base de données.


Index et performance d'écriture

Les index ne sont pas gratuits. Chaque fois qu'un enregistrement est créé, mis à jour ou supprimé, PostgreSQL doit mettre à jour tous les index de cette table également. Sur les tables avec de nombreux index, les opérations d'écriture prennent légèrement plus de temps. Pour la plupart des cas d'utilisation d'Odoo, ce compromis en vaut la peine, mais il est important de comprendre que tout indexer n'est pas toujours la bonne réponse.

L'option index='trigram'

Dans Odoo 16 et les versions ultérieures, l'attribut index accepte non seulement True mais aussi la valeur chaîne 'trigram'. Cela crée un index trigramme GIN en utilisant l'extension PostgreSQL pg_trgm, qui prend en charge le filtrage de motifs rapide avec des requêtes ILIKE. Cela est particulièrement utile pour la recherche de texte sur des champs comme les noms de produits ou les noms de partenaires où les utilisateurs saisissent souvent des chaînes partielles dans la barre de recherche.


name = fields.Char(string='Nom du produit', index='trigram')

C'est une option plus avancée utilisée dans les propres modules standard d'Odoo pour les champs qui sont fréquemment recherchés par texte partiel.

Cas d'utilisation commerciale


Les champs indexés apparaissent dans de nombreux flux de travail réels d'Odoo. Voici cinq exemples pratiques où l'indexation d'un champ fait une différence notable.


1. CRM : Filtrer les prospects par vendeur

Dans le CRM, les responsables des ventes filtrent régulièrement le pipeline par vendeur. Le champ user_id sur crm.lead est indexé par défaut dans Odoo, ce qui rend le filtrage par vendeur rapide même avec des milliers de prospects. Si vous ajoutez un champ Many2one personnalisé pointant vers un utilisateur ou une équipe, son indexation suit la même logique.


2. Ventes : Rechercher des commandes par statut

Le champ state sur sale.order est indexé. C'est ce qui rend le chargement de la liste des commandes confirmées, ou le filtrage des commandes en attente de livraison, rapide pour les entreprises traitant de grands volumes. Les champs de sélection qui sont fréquemment utilisés comme critères de filtrage sont de bons candidats pour l'indexation.


3. Inventaire : Suivre les mouvements par produit

Les mouvements de stock dans Odoo peuvent atteindre des volumes très importants, en particulier dans les entreprises de distribution ou de fabrication. Le champ product_id sur stock.move est indexé, ce qui rend efficace la requête de tous les mouvements pour un produit spécifique. Sans cet index, les rapports de traçabilité des produits deviendraient douloureusement lents dans les entrepôts occupés.


4. Comptabilité : Filtrer les écritures comptables par partenaire

Les comptables ouvrent fréquemment le grand livre pour un client ou un fournisseur spécifique. Le champ partner_id sur account.move.line est indexé pour rendre ces recherches efficaces. Dans les entreprises ayant des années d'historique comptable, cet index est ce qui empêche le rapport des créances âgées de dépasser le délai.


5. Modules personnalisés : Champs de référence pour la traçabilité

Lors de la création de modules personnalisés, il est courant d'ajouter des champs de référence qui lient des enregistrements à travers des modèles, par exemple un code de projet personnalisé ou un numéro de document externe. Si les utilisateurs recherchent ou filtrent régulièrement par ce champ de référence, ajouter index=True est un moyen simple de garder ces recherches rapides à mesure que les données augmentent.


Créer ou personnaliser un champ indexé


En Python (Développement de modules personnalisés)

Ajouter index=True à une définition de champ dans un module Python est simple. Il vous suffit de l'inclure en tant qu'argument clé lors de la déclaration du champ :


from odoo import models, fields

class ProjectTask(models.Model):
    _inherit = 'project.task'

    x_external_ref = fields.Char(
        string='Référence Externe',
        index=True,
        help='Numéro de référence du système externe'
    )

Après avoir ajouté ce champ à votre module, exécutez odoo-bin -u your_module_name ou mettez à jour le module via le menu Apps. Odoo détectera le nouveau champ et créera l'index correspondant dans la base de données.


Vous pouvez également ajouter un index à un champ existant en l'héritant et en remplaçant la définition, bien que cette approche nécessite de la prudence pour éviter des effets secondaires indésirables sur le comportement du champ original.


Dans Odoo Studio

Odoo Studio permet aux utilisateurs non techniques de créer des champs via l'interface. Cependant, Studio n'expose actuellement pas d'option pour activer ou désactiver l'indexation lors de la création de champs. Les champs créés via Studio sont stockés dans la base de données en tant que champs manuels et n'ont pas index=True défini par défaut.


Si vous avez besoin qu'un champ créé par Studio soit indexé pour des raisons de performance, le chemin le plus propre est de convertir la personnalisation de Studio en un véritable module Python et d'ajouter index=True dans le code. Cela relève de la personnalisation technique et est généralement géré par un développeur Odoo plutôt que par un utilisateur de Studio.


Ajouter un Index Directement dans PostgreSQL

Dans certaines situations, comme lors de l'optimisation d'une base de données de production existante sans mise à jour de module, un administrateur de base de données peut ajouter un index directement en utilisant SQL :

CREATE INDEX CONCURRENTLY idx_sale_order_partner_id
ON sale_order (partner_id);

Utiliser CONCURRENTLY évite de verrouiller la table pendant la création de l'index, ce qui est important dans les environnements de production. Cela dit, cette approche doit être coordonnée avec la définition du module Odoo pour garder le code Python et la base de données synchronisés. Si le module est ensuite mis à jour, Odoo peut ou non gérer l'index en fonction de ce qui se trouve dans la définition du champ.


Meilleures pratiques


Champs d'Index qui Apparaissent dans les Domaines de Recherche

Si un champ est régulièrement utilisé dans des filtres de domaine, que ce soit dans des filtres de vue liste, des actions automatisées, des tâches planifiées ou des dépendances de champs calculés, c'est un bon candidat pour l'indexation. Les exemples les plus courants sont les champs relationnels Many2one, les champs d'état et les champs de référence ou de code.


Suivez les propres conventions d'Odoo

La meilleure référence pour savoir quand utiliser index=True est le propre code source d'Odoo. Regardez les définitions de champs standard dans sale.order, account.move ou stock.move pour voir quels champs les propres développeurs d'Odoo ont choisi d'indexer. Ces choix sont basés sur de réels modèles d'utilisation et des données de performance provenant de milliers de bases de données de production.


Indexez toujours les champs Many2one sur les modèles à fort volume

Pour les modèles qui accumulent un grand nombre d'enregistrements au fil du temps (écritures de journal, mouvements de stock, lignes de commande de vente), indexez toujours les champs Many2one qui sont utilisés pour le filtrage. Le coût d'un index supplémentaire sur une table à forte écriture vaut presque toujours l'amélioration de la performance en lecture.


Envisagez l'indexation Trigram pour les champs de recherche textuelle

Sur Odoo 16 et versions ultérieures, si les utilisateurs recherchent fréquemment des enregistrements en tapant des chaînes partielles dans un champ Char tel qu'un nom de produit, un nom de partenaire ou une référence de document, envisagez d'utiliser index='trigram' au lieu de l'index B-arbre par défaut. Les index Trigram sont spécifiquement conçus pour la correspondance de motifs ILIKE.


Vérifiez que les index sont effectivement utilisés

Après avoir ajouté un index, vous pouvez vérifier que PostgreSQL l'utilise en exécutant un EXPLAIN ANALYZE sur la requête. Si le planificateur de requêtes choisit toujours un scan séquentiel, la table peut être trop petite pour que l'index soit bénéfique, ou les conditions de la requête peuvent ne pas être compatibles avec le type d'index.


Documentez vos décisions d'indexation

Lors de la création de modules personnalisés, laissez un bref commentaire expliquant pourquoi un champ est indexé. Cela aide les futurs développeurs et consultants à comprendre l'intention et à éviter de supprimer l'index par accident lors d'un refactoring.

Pièges courants


Indexation de chaque champ par défaut

Une erreur courante lors de l'apprentissage de l'indexation est d'ajouter index=True à chaque champ juste pour être sûr. Cela est contre-productif. Chaque index occupe de l'espace de stockage et ajoute une surcharge à chaque opération d'écriture. Sur les tables qui reçoivent un volume élevé d'inserts ou de mises à jour, des index inutiles peuvent ralentir considérablement le système.


Indexation des champs sur de petites tables

Sur les tables avec quelques centaines de lignes, le planificateur de requêtes de PostgreSQL décide souvent qu'un scan séquentiel est plus rapide que l'utilisation d'un index. Les index commencent à apporter un réel avantage à mesure que les tables croissent pour atteindre des milliers d'enregistrements et au-delà. L'indexation de petites tables de recherche ou de modèles personnalisés rarement peuplés ajoute de la complexité sans aucun avantage pratique.


Oublier de mettre à jour le module après avoir ajouté index=True

Ajouter simplement index=True à une définition de champ en Python ne crée pas automatiquement l'index dans la base de données. Vous devez mettre à jour le module en utilisant -u module_name ou via le backend Odoo. Oublier cette étape est une source fréquente de confusion lors du développement et peut entraîner des problèmes de performance dans les environnements de staging ou de production où la mise à jour a été omise.


S'attendre à ce que les index accélèrent les recherches ILIKE sur les champs Char

Un index B-tree régulier avec index=True n'aide pas avec les requêtes ILIKE '%keyword%' où le caractère générique est au début du motif. PostgreSQL ne peut pas utiliser un index B-tree pour évaluer un caractère générique en tête. Si vous avez besoin d'une recherche textuelle partielle rapide, utilisez index='trigram' sur Odoo 16+ ou explorez les options de recherche en texte intégral.


Ne pas considérer les champs calculés stockés

Les champs calculés stockés (ceux avec store=True) ont bien une colonne dans la base de données et peuvent être indexés. Les développeurs négligent parfois cela et manquent une opportunité d'améliorer les performances sur les champs qui agrègent ou dérivent des valeurs utilisées intensivement dans les filtres. Si un champ calculé stocké apparaît dans des filtres de domaine à travers des rapports ou des vues, il vaut la peine de considérer son indexation.

Conclusion


L'attribut index=True est un petit détail dans la définition de champ Odoo, mais il a un réel impact sur la performance de la base de données à mesure que vos données croissent. Utilisé correctement, il maintient les recherches rapides, les vues de liste réactives et les rapports rapides à générer. Utilisé sans précaution, il ajoute une surcharge sans aucun bénéfice.


La conclusion clé est simple : indexez les champs qui sont régulièrement utilisés dans les filtres de domaine, en particulier les champs Many2one sur des modèles à fort volume. Suivez les modèles établis par les propres modules standards d'Odoo. Évitez de sur-indexer les petites tables ou les champs qui ne sont jamais filtrés. Et si vous êtes sur Odoo 16 ou plus, envisagez index='trigram' pour les champs de recherche textuelle où les utilisateurs saisissent des chaînes partielles.


Obtenir la bonne stratégie d'indexation dès le début d'un projet de développement personnalisé est beaucoup plus facile que de diagnostiquer des requêtes lentes en production plus tard.

Vous travaillez sur une implémentation Odoo ?


Chez Dasolo, nous aidons les entreprises à mettre en œuvre, personnaliser et optimiser Odoo. Que vous construisiez des modules personnalisés, amélioriez les performances d'une instance existante ou planifiiez un nouveau projet Odoo depuis le début, nous apportons une expertise technique pratique à chaque engagement.


Si vous êtes confronté à des requêtes lentes, des personnalisations complexes ou si vous avez besoin de conseils sur les meilleures pratiques de développement Odoo, nous sommes heureux de vous aider. Contactez l'équipe de Dasolo et faites-nous savoir sur quoi vous travaillez.

Champ indexé dans Odoo : Un guide pratique pour les développeurs et les consultants
Dasolo 6 mars 2026
Partager cet article
Se connecter pour laisser un commentaire.