Einführung
Wenn Sie schon einmal Odoo‑Modelle erstellt oder geprüft haben, ist Ihnen wahrscheinlich das unscheinbare Attribut index=True begegnet. Auf den ersten Blick wirkt es wie ein kleines Detail — doch hinter dieser Einstellung steckt eine datenbankseitige Entscheidung, die das Verhalten von Such- und Filteraktionen deutlich beeinflussen kann, sobald Tabellen groß werden.
Dieses Kapitel erklärt knapp und praxisorientiert, was ein indexiertes Feld im Kontext des Odoo‑Datenmodells bedeutet, welche Auswirkungen es auf PostgreSQL hat und wann Sie es bei Eigenentwicklungen sinnvoll einsetzen sollten. Die Kenntnis dieses Mechanismus hilft, fundierte Entscheidungen für Performance und Wartbarkeit zu treffen.
Was bedeutet ein indexiertes Feld in Odoo?
In Odoo wird ein Feld als indexiert markiert, wenn in seiner Deklaration index=True steht. Beim Installieren oder Aktualisieren eines Moduls veranlasst Odoo PostgreSQL, für die entsprechende Spalte einen Index anzulegen — standardmäßig einen B‑Tree‑Index.
Im Kern bedeutet das: eine kleine Änderung in der Felddefinition reicht aus, damit Odoo beim nächsten Schemaabgleich das Datenbankschema um einen Index ergänzt.
Beispielhaft würde man in einer Python‑Moduldefinition ein Feld so anlegen: reference = fields.Char(string='Reference', index=True) — das ist die Stelle, an der Sie das Index‑Flag setzen, damit Odoo später die Indexerstellung veranlasst.
Für Anwenderoberflächen bleibt alles gleich: Nutzer sehen keine Kennzeichnung, ob ein Feld indexiert ist oder nicht. Das Thema spielt sich vollständig auf der Datenbankebene ab und hat keine direkte Auswirkung auf das Formular‑Layout oder die Ansichtskonzepte in Odoo.
Die praktische Auswirkung betrifft die Performance: mit einem Index kann PostgreSQL gezielt passende Zeilen finden, ohne die gesamte Tabelle zeilenweise durchsuchen zu müssen. Das ist bei großen Datenmengen der Unterschied zwischen akzeptabler Reaktionszeit und spürbar langsamer Suche.
Welche Feldtypen unterstützen index=True in Odoo
Grundsätzlich lassen sich die meisten skalaren Feldtypen mit einem Index versehen — das sind die Kandidaten, bei denen die Option sinnvoll angewendet werden kann.
- Char‑ und Text‑Felder
- Integer‑ und Float‑Felder
- Date‑ und Datetime‑Felder
- Selection‑Felder
- Many2one‑Felder (sehr häufig indexiert)
- Boolean‑Felder
Beziehungsfelder wie One2many oder Many2many haben nicht dieselbe einzelne Datenbankspalte, daher ist das Index‑Flag dort nicht relevant. Ebenso können nicht gespeicherte (compute without store) Felder nicht indexiert werden, da ihnen eine physische Spalte in der DB fehlt.
Wie das Feld auf Datenbankebene wirkt
Bei Modulinstallation oder -upgrade liest Odoo die Felddefinitionen aus und synchronisiert das Schema. Für jedes Feld mit index=True erzeugt Odoo die passende SQL‑Anweisung zur Anlage des Indexes in PostgreSQL.
PostgreSQL erzeugt standardmäßig einen B‑Tree‑Index, der sich besonders für Gleichheitsbedingungen, Bereichsabfragen und Sortierungen eignet — also für die meisten Filter‑ und Suchfälle in Odoo‑Listen und Domains.
Wie sich Indexe mit dem Odoo ORM verhalten
Der ORM übersetzt Python‑Domains in SQL‑WHERE‑Bedingungen. Bei einer Kondition wie [('state','=', 'sale')] entsteht ein WHERE state = 'sale'. Existiert für dieses Feld ein Index, nutzt der Query‑Planner diesen, um die passenden Zeilen schnell zu lokalisieren statt die Tabelle komplett zu scannen.
Ein typischer Alltagsfall sind Many2one‑Felder: partner_id speichert die ID des zugehörigen Partners. Filtert man Bestellungen nach Kunde, entsteht ein WHERE partner_id = X — mit Index bleibt diese Abfrage auch bei Hunderttausenden Datensätzen performant.
Indexe und Schreibperformance
Indexe kosten Schreibaufwand: bei INSERT, UPDATE oder DELETE muss PostgreSQL alle relevanten Indexstrukturen pflegen. Je mehr Indexe auf einer Tabelle liegen, desto größer der Einfluss auf Schreiboperationen. In den meisten Fällen ist der Kompromiss zulässig, doch pauschales Indexieren aller Felder ist nicht ratsam.
Die Option index='trigram'
Ab Odoo 16 kann index statt True auch den String 'trigram' annehmen. Das legt einen GIN‑Trigram‑Index (pg_trgm) an, der besonders bei ILIKE‑ bzw. Teilstring‑Suchen deutlich schneller ist und deshalb für Felder wie Produkt‑ oder Partnernamen interessant sein kann.
Beispiel: name = fields.Char(string='Product Name', index='trigram') — das ist eine gezielte Optimierung für unscharfe oder teilstringbasierte Suchen.
Diese Option verwendet Odoo bereits in Standardmodulen für Felder, die häufig per Teilstring gesucht werden und deshalb von einem Trigramm‑Index profitieren.
Wann sich Indexierung im Alltag auszahlt
Fünf praktische Anwendungsfälle für indexierte Felder
1) CRM: Leads nach Zuständigen filtern
Im CRM filtern Manager häufig die Pipeline nach verantwortlichem Vertriebsmitarbeiter. Das Feld user_id ist standardmäßig indexiert, sodass Filter auch bei großen Lead‑Mengen schnell bleiben. Für eigene Many2one‑Felder mit ähnlicher Funktionalität gilt dasselbe.
2) Vertrieb: Bestellungen nach Status suchen
Das Statusfeld (state) bei Verkaufsaufträgen ist indexiert, wodurch das Laden bestimmter Bestellzustände auch bei hohem Durchsatz flott bleibt. Auswahlfelder, die regelmäßig als Filter eingesetzt werden, sind gute Kandidaten für einen Index.
3) Lager: Bewegungen pro Produkt nachverfolgen
In Logistikumgebungen können Stock‑Move‑Tabellen sehr groß werden. Ein Index auf product_id macht Abfragen zu Produktbewegungen effizient und verhindert, dass Nachverfolgbarkeits‑Reports bei viel Betrieb unerträglich langsam werden.
4) Buchhaltung: Buchungszeilen nach Geschäftspartner filtern
Buchhalter öffnen oft das Journal für einen bestimmten Kunden oder Lieferanten. Ein Index auf partner_id in Buchungszeilen sorgt dafür, dass solche Suchen in historischen Datenbeständen schnell bleiben und Berichte nicht wegen Timeouts fehlschlagen.
5) Eigenentwicklungen: Referenzfelder für Nachvollziehbarkeit
Bei eigenen Modulen werden häufig Referenzfelder (z. B. externe Belegnummern) angelegt. Wenn Anwender regelmäßig danach suchen oder filtern, sollte man von Anfang an ein Index‑Flag setzen, damit die Performance auch bei wachsendem Datenvolumen erhalten bleibt.
So legen Sie ein indexiertes Feld an oder passen es an
Indexierung in Python‑Modulen (Custom Development)
Das Hinzufügen von index=True in einer Felddefinition ist im Code simpel: man ergänzt das Keyword beim Feldaufruf in der Klassendeklaration.
Beispiel für eine Erweiterung: x_external_ref = fields.Char(string='External Reference', index=True, help='Reference number from the external system') — danach ist ein Modulupgrade nötig, damit der Index tatsächlich angelegt wird.
Nach dem Code‑Änderungsschritt müssen Sie das Modul upgraden (z. B. odoo-bin -u your_module_name oder über das Apps‑Menü), damit Odoo die neue Indexdefinition erkennt und in der Datenbank erstellt.
Auch das Nachrüsten eines Index für ein bestehendes Feld ist möglich, indem man das Feld per Inheritance überschreibt; dabei ist jedoch Vorsicht geboten, um unbeabsichtigte Seiteneffekte zu vermeiden.
Indexierung über Odoo Studio
Odoo Studio erlaubt Endanwendern das Erstellen von Feldern per GUI, bietet aber derzeit keine Option, Indexe über die Oberfläche zu aktivieren. Studio‑Felder werden ohne index=True als manuelle Felder angelegt.
Wenn ein Studio‑Feld indexiert werden soll, ist die sauberste Lösung, die Anpassung in ein richtiges Python‑Modul zu überführen und dort index=True zu setzen — das ist in der Regel Aufgabe eines Entwicklers.
Index direkt in PostgreSQL anlegen
In produktiven Systemen, in denen Sie keine Moduländerung ausrollen wollen, kann ein DBA auch direkt einen Index per SQL anlegen, um Performance‑Probleme schnell zu adressieren.
Beispiel: CREATE INDEX CONCURRENTLY idx_sale_order_partner_id ON sale_order (partner_id);
Der Zusatz CONCURRENTLY ist wichtig, da so die Tabelle während der Indexerstellung nicht gesperrt wird. Solche manuellen Eingriffe sollten jedoch mit dem Modulcode abgestimmt werden, damit DB‑Schema und Felddefinitionen nicht auseinanderlaufen.
Empfohlene Vorgehensweisen
Welche Felder sollten auf jeden Fall indexiert werden?
Felder, die häufig in Domains auftauchen — etwa in Listenfiltern, automatisierten Aktionen, geplanten Jobs oder als Abfragebedingungen für Berichte — sind gute Kandidaten. Besonders Many2one‑Beziehungen, Status‑/State‑Felder sowie Referenz‑ und Codefelder werden oft gefiltert und profitieren von einem Index.
Orientieren Sie sich an Odoos eigenen Entscheidungen
Ein verlässlicher Anhaltspunkt sind die Standardmodule: schauen Sie, welche Felder Odoo selbst indexiert. Diese Auswahl basiert auf realen Nutzungsdaten und gibt gute Hinweise für eigene Projekte.
Many2one‑Felder bei volumenstarken Modellen immer indexieren
Bei Modellen, die im Laufe der Zeit groß werden (z. B. Journalbuchungen, Lagerbewegungen, Verkaufszeilen), lohnt sich fast immer ein Index auf Many2one‑Felder, denn der Gewinn bei Lesezugriffen überwiegt meist die zusätzliche Schreibkosten.
Trigramm‑Index für Textsuche in Erwägung ziehen
Ab Odoo 16 sollten Sie für Felder, in denen Nutzer per Teilstring suchen (Produktname, Partnername, Dokumentnummer), index='trigram' in Betracht ziehen. Trigramm‑Indizes sind für ILIKE‑Suchen mit unbekannten Wortteilen optimiert.
Prüfen, ob der Index tatsächlich genutzt wird
Nach dem Anlegen eines Index prüfen Sie mit EXPLAIN ANALYZE, ob PostgreSQL den Index im Ausführungsplan verwendet. Bei sehr kleinen Tabellen oder inkompatiblen Abfragen kann der Planner weiterhin einen SeqScan bevorzugen.
Dokumentieren Sie Ihre Index‑Entscheidungen
Hinterlassen Sie im Code einen kurzen Kommentar, warum ein Feld indexiert wurde. Das hilft späteren Entwicklern, die Intention zu verstehen und verhindert versehentliches Entfernen bei Refactorings.
Häufige Fehlerquellen
Indexieren nicht pauschal für alle Felder
Ein häufiger Anfängerfehler ist, vorsorglich jedes Feld zu indexieren. Das erzeugt Speicher- und CPU‑Overhead und verlangsamt Schreiboperationen unnötig — besonders bei stark beschriebenen Tabellen.
Indexe auf sehr kleinen Tabellen sind oft unnötig
Bei Tabellen mit wenigen Hundert Zeilen ist häufig ein Sequenzscan schneller als die Verwendung eines Indexes. Indexe lohnen sich meist erst ab einigen tausend Datensätzen — bei kleinen Lookup‑Tabellen verursachen sie nur Aufwand ohne praktischen Nutzen.
Upgrade des Moduls nicht vergessen
Ändern Sie im Code ein Feld und setzen index=True, erstellt Odoo den Index nicht automatisch ohne Modulupgrade. Das Vergessen des Upgrades ist eine häufige Ursache dafür, dass erwartete Performanceverbesserungen ausbleiben.
B‑Tree‑Index hilft nicht bei führenden Wildcards
Ein normaler B‑Tree‑Index unterstützt keine Abfragen wie ILIKE '%suchbegriff%' mit führendem Prozentzeichen. Für solche Fälle sind Trigramm‑Indizes oder Full‑Text‑Search die richtige Wahl.
Gespeicherte berechnete Felder nicht übersehen
Compute‑Felder mit store=True haben eine physische Spalte und können indexiert werden. Entwickler übersehen das manchmal und verschenken so Performance‑Potential für oft gefilterte, abgeleitete Werte.
Fazit
Kurzfazit zur Bedeutung von index=True
Das Attribut index=True ist ein kleines Detail mit großer Wirkung: richtig angewendet hält es Suchen und Listenansichten schnell, falsch oder übertrieben eingesetzt verursacht Overhead. Merke: indexieren, was regelmäßig in Domains auftaucht — besonders Many2one‑Felder bei volumenstarken Modellen — und auf Odoo 16+ bei Teilstringsuche index='trigram' prüfen.
Eine durchdachte Index‑Strategie von Anfang an erspart Ihnen später viel Aufwand bei der Fehlersuche und Optimierung in produktiven Systemen.
Arbeiten Sie an einer Odoo‑Einführung?
Bei Dasolo unterstützen wir Unternehmen bei Implementierung, Anpassung und Performance‑Optimierung von Odoo. Egal ob Neuentwicklung, Analyse eines bestehenden Systems oder komplette Projektbegleitung — wir bringen technisches Know‑how in jedes Mandat ein.
Wenn Sie mit langsamen Abfragen, komplexen Anpassungen oder Fragen zu Odoo‑Entwicklungsrichtlinien konfrontiert sind, beraten wir Sie gern. Kontaktieren Sie das Dasolo‑Team und schildern Sie kurz Ihr Vorhaben — wir melden uns mit konkreten Vorschlägen zurück.