Einführung
Wenn Sie Zeit damit verbracht haben, Odoo-Felddefinitionen zu schreiben oder zu überprüfen, sind Sie wahrscheinlich auf etwas gestoßen wie index=True bei einem Feld. Es sieht klein aus, fast wie ein nachträglicher Gedanke. Aber dieses einzelne Attribut kann einen bedeutenden Unterschied darin machen, wie schnell Ihre Odoo-Instanz reagiert, wenn Benutzer große Datensätze durchsuchen, filtern oder navigieren.
Dieser Leitfaden erläutert, was ein indiziertes Feld im Kontext des Odoo-Datenmodells tatsächlich ist, wie es Ihre Datenbank beeinflusst und wann es sinnvoll ist, es in Ihrer eigenen Odoo-Entwicklungsarbeit zu verwenden. Egal, ob Sie ein benutzerdefiniertes Modul erstellen oder eine bestehende Implementierung überprüfen, das Verständnis dieses Konzepts wird Ihnen helfen, bessere Entscheidungen zu treffen.
Was ist ein indiziertes Feld in Odoo
Im Odoo ORM wird ein Feld als indiziert erklärt, wenn seine Definition index=True enthält. Dies sagt Odoo, dass PostgreSQL aufgefordert wird, einen B-Baum-Index auf der entsprechenden Datenbankspalte zu erstellen, wenn das Modul installiert oder aktualisiert wird.
Hier ist ein einfaches Beispiel aus einer Odoo-Felddefinition in Python:
class SaleOrder(models.Model):
_name = 'sale.order'
reference = fields.Char(string='Reference', index=True)
state = fields.Selection([...], index=True)
partner_id = fields.Many2one('res.partner', index=True)
Aus der Perspektive der Benutzeroberfläche gibt es nichts Sichtbares über indizierte Felder. Ein Benutzer, der ein Formular ausfüllt oder eine Listenansicht durchsucht, hat keine Möglichkeit zu wissen, ob ein Feld indiziert ist oder nicht. Das Indizieren ist völlig eine Angelegenheit auf Datenbankebene.
Was es beeinflusst, ist die Geschwindigkeit. Wenn ein Feld indiziert ist, kann PostgreSQL übereinstimmende Datensätze viel schneller finden, insbesondere in Tabellen mit Tausenden oder Millionen von Zeilen. Ohne einen Index muss die Datenbank jede Zeile in der Tabelle durchsuchen, um die zu finden, die Ihren Suchkriterien entsprechen. Mit einem Index navigiert sie durch eine sortierte Struktur und findet die Ergebnisse direkt.
Welche Odoo-Feldtypen unterstützen index=True
Die meisten skalaren Feldtypen im Odoo ORM unterstützen das index-Attribut:
- Char- und Text-Felder
- Integer- und Float-Felder
- Date- und Datetime-Felder
- Selection-Felder
- Many2one-Felder (sehr häufig indiziert)
- Boolean-Felder
Relationale Felder wie One2many und Many2many haben keinen direkten Spaltenindex wie andere, daher ist das index-Attribut für sie nicht relevant. Berechnete Felder, die nicht gespeichert werden, können ebenfalls nicht indiziert werden, da sie keine Datenbankspalte haben.
Wie das Feld funktioniert
Wenn Odoo ein Modul initialisiert oder aktualisiert, liest es alle Felddefinitionen und synchronisiert das Datenbankschema. Für jedes Feld mit index=True führt Odoo eine SQL-Anweisung aus, um einen Index auf dieser Spalte in PostgreSQL zu erstellen.
Standardmäßig erstellt PostgreSQL einen B-Baum-Index, der der Standardindextyp ist und gut für Gleichheitsvergleiche (=), Bereichsabfragen (>, <, BETWEEN) und Sortierung funktioniert. Dies deckt den Großteil dessen ab, was Odoo beim Filtern von Datensätzen in Listenansichten oder beim Berechnen von domänenbasierten Suchen tut.
Wie es mit dem Odoo ORM interagiert
Das Odoo ORM übersetzt Python-Domänenfilter in SQL-Abfragen. Wenn Sie eine Domäne wie [('state', '=', 'sale')] schreiben, generiert das ORM etwas wie WHERE state = 'sale'. Wenn das state-Feld einen Index hat, verwendet PostgreSQL diesen, um diese Bedingung effizient zu lösen, ohne die gesamte Tabelle zu scannen.
Many2one-Felder sind ein sehr häufiger Anwendungsfall. Im Datenmodell von Odoo speichert ein Feld wie partner_id in einem Verkaufsauftrag die ganzzahlige ID des zugehörigen Partners. Wenn Sie die Liste der Aufträge nach Kunde gefiltert öffnen, führt Odoo eine Abfrage mit einer WHERE partner_id = X-Bedingung aus. Mit einem Index auf partner_id ist diese Suche schnell, selbst bei Hunderttausenden von Aufträgen in der Datenbank.
Indizes und Schreibleistung
Indizes sind nicht kostenlos. Jedes Mal, wenn ein Datensatz erstellt, aktualisiert oder gelöscht wird, muss PostgreSQL alle Indizes auf dieser Tabelle ebenfalls aktualisieren. Bei Tabellen mit vielen Indizes dauern Schreiboperationen etwas länger. Für die meisten Odoo-Anwendungsfälle ist dieser Kompromiss es wert, aber es ist wichtig zu verstehen, dass das Indizieren von allem nicht immer die richtige Antwort ist.
Die Option index='trigram'
In Odoo 16 und späteren Versionen akzeptiert das index-Attribut nicht nur True, sondern auch den Stringwert 'trigram'. Dies erstellt einen GIN-Trigramm-Index unter Verwendung der pg_trgm-PostgreSQL-Erweiterung, die schnelles Muster-Matching mit ILIKE-Abfragen unterstützt. Dies ist besonders nützlich für die Textsuche in Feldern wie Produktnamen oder Partnernamen, bei denen Benutzer häufig Teilstrings in die Suchleiste eingeben.
name = fields.Char(string='Produktname', index='trigram')
Dies ist eine fortgeschrittenere Option, die in Odos eigenen Standardmodulen für Felder verwendet wird, die häufig nach Teiltexten durchsucht werden.
Geschäftsanwendungsfälle
Indizierte Felder kommen in vielen realen Odoo-Workflows vor. Hier sind fünf praktische Beispiele, bei denen die Indizierung eines Feldes einen spürbaren Unterschied macht.
1. CRM: Leads nach Verkäufer filtern
Im CRM filtern Vertriebsleiter regelmäßig die Pipeline nach Verkäufer. Das user_id-Feld auf crm.lead ist standardmäßig in Odoo indiziert, was das Filtern nach Verkäufer schnell macht, selbst bei Tausenden von Leads. Wenn Sie ein benutzerdefiniertes Many2one-Feld hinzufügen, das auf einen Benutzer oder ein Team verweist, folgt die Indizierung derselben Logik.
2. Vertrieb: Bestellungen nach Status suchen
Das state-Feld auf sale.order ist indiziert. Das macht das Laden der Liste bestätigter Bestellungen oder das Filtern nach Bestellungen, die auf die Lieferung warten, schnell für Unternehmen, die große Volumina verarbeiten. Auswahlfelder, die häufig als Filterkriterien verwendet werden, sind gute Kandidaten für die Indizierung.
3. Lager: Bewegungen nach Produkt verfolgen
Lagerbewegungen in Odoo können sehr große Volumina erreichen, insbesondere in Vertriebs- oder Fertigungsunternehmen. Das product_id-Feld auf stock.move ist indiziert, was es effizient macht, alle Bewegungen für ein bestimmtes Produkt abzufragen. Ohne diesen Index würden Produktverfolgbarkeitsberichte in stark frequentierten Lagern schmerzhaft langsam werden.
4. Buchhaltung: Journalbuchungen nach Partner filtern
Buchhalter öffnen häufig das Hauptbuch für einen bestimmten Kunden oder Lieferanten. Das partner_id auf account.move.line ist indiziert, um diese Abfragen effizient zu gestalten. In Unternehmen mit jahrelanger Buchhaltungshistorie ist dieser Index das, was den Bericht über die überfälligen Forderungen vor einem Timeout bewahrt.
5. Benutzerdefinierte Module: Referenzfelder für die Nachverfolgbarkeit
Beim Erstellen benutzerdefinierter Module ist es üblich, Referenzfelder hinzuzufügen, die Datensätze über Modelle hinweg verknüpfen, beispielsweise einen benutzerdefinierten Projektcode oder eine externe Dokumentennummer. Wenn Benutzer regelmäßig nach diesem Referenzfeld suchen oder filtern, ist das Hinzufügen von index=True eine unkomplizierte Möglichkeit, diese Suchen schnell zu halten, während die Daten wachsen.
Erstellen oder Anpassen eines indizierten Feldes
In Python (Entwicklung benutzerdefinierter Module)
Das Hinzufügen von index=True zu einer Felddefinition in einem Python-Modul ist unkompliziert. Sie fügen es einfach als Schlüsselwortargument bei der Deklaration des Feldes hinzu:
from odoo import models, fields
class ProjectTask(models.Model):
_inherit = 'project.task'
x_external_ref = fields.Char(
string='Externe Referenz',
index=True,
help='Referenznummer aus dem externen System'
)
Nachdem Sie dieses Feld zu Ihrem Modul hinzugefügt haben, führen Sie odoo-bin -u your_module_name aus oder aktualisieren Sie das Modul über das Apps-Menü. Odoo erkennt das neue Feld und erstellt den entsprechenden Index in der Datenbank.
Sie können auch einen Index zu einem bestehenden Feld hinzufügen, indem Sie es erben und die Definition überschreiben, obwohl dieser Ansatz Vorsicht erfordert, um unbeabsichtigte Nebenwirkungen auf das Verhalten des ursprünglichen Feldes zu vermeiden.
In Odoo Studio
Odoo Studio ermöglicht es nicht-technischen Benutzern, Felder über die Benutzeroberfläche zu erstellen. Allerdings bietet Studio derzeit keine Option, um das Indizieren beim Erstellen von Feldern ein- oder auszuschalten. Felder, die über Studio erstellt werden, werden in der Datenbank als manuelle Felder gespeichert und haben standardmäßig kein index=True gesetzt.
Wenn Sie ein in Studio erstelltes Feld aus Leistungsgründen indizieren müssen, ist der sauberste Weg, die Studio-Anpassung in ein richtiges Python-Modul zu konvertieren und index=True im Code hinzuzufügen. Dies fällt unter technische Anpassungen und wird typischerweise von einem Odoo-Entwickler und nicht von einem Studio-Benutzer durchgeführt.
Einen Index direkt in PostgreSQL hinzufügen
In einigen Situationen, wie z.B. bei der Optimierung einer bestehenden Produktionsdatenbank ohne Modulaktualisierung, kann ein Datenbankadministrator einen Index direkt mit SQL hinzufügen:
CREATE INDEX CONCURRENTLY idx_sale_order_partner_id
ON sale_order (partner_id);
Die Verwendung von CONCURRENTLY vermeidet das Sperren der Tabelle während der Indexerstellung, was in Produktionsumgebungen wichtig ist. Dennoch sollte dieser Ansatz mit der Odoo-Moduldefinition koordiniert werden, um den Python-Code und die Datenbank synchron zu halten. Wenn das Modul später aktualisiert wird, kann Odoo den Index möglicherweise verwalten oder auch nicht, abhängig davon, was in der Felddefinition enthalten ist.
Best Practices
Indexfelder, die in Suchdomänen erscheinen
Wenn ein Feld regelmäßig in Domainfiltern verwendet wird, sei es in Listenansichtfiltern, automatisierten Aktionen, geplanten Jobs oder abhängigen berechneten Feldern, ist es ein guter Kandidat für die Indizierung. Die häufigsten Beispiele sind Many2one-Beziehungsfelder, Statusfelder und Referenz- oder Codefelder.
Befolgen Sie die eigenen Konventionen von Odoo
Die beste Referenz dafür, wann index=True verwendet werden sollte, ist der Quellcode von Odoo selbst. Schauen Sie sich die Standardfelddefinitionen in sale.order, account.move oder stock.move an, um zu sehen, welche Felder die eigenen Entwickler von Odoo zur Indizierung ausgewählt haben. Diese Entscheidungen basieren auf realen Nutzungsmustern und Leistungsdaten aus Tausenden von Produktionsdatenbanken.
Indizieren Sie immer Many2one-Felder in Modellen mit hohem Volumen
Für Modelle, die im Laufe der Zeit eine große Anzahl von Datensätzen ansammeln (Journalbuchungen, Lagerbewegungen, Verkaufsauftragszeilen), indizieren Sie immer die Many2one-Felder, die für Filterungen verwendet werden. Die Kosten für einen zusätzlichen Index in einer schreibintensiven Tabelle sind fast immer den Leistungsverbesserungen beim Lesen wert.
Berücksichtigen Sie die Trigramm-Indizierung für Textsuchfelder
In Odoo 16 und später, wenn Benutzer häufig nach Datensätzen suchen, indem sie Teilstrings in einem Char-Feld wie einem Produktnamen, Partnernamen oder Dokumentenreferenz eingeben, sollten Sie in Betracht ziehen, index='trigram' anstelle des Standard-Baumindex zu verwenden. Trigramm-Indizes sind speziell für ILIKE-Musterabgleiche konzipiert.
Überprüfen Sie, ob Indizes tatsächlich verwendet werden
Nachdem Sie einen Index hinzugefügt haben, können Sie überprüfen, ob PostgreSQL ihn verwendet, indem Sie ein EXPLAIN ANALYZE für die Abfrage ausführen. Wenn der Abfrageplaner immer noch einen sequenziellen Scan wählt, könnte die Tabelle zu klein sein, damit der Index vorteilhaft ist, oder die Abfragebedingungen sind möglicherweise nicht mit dem Indextyp kompatibel.
Dokumentieren Sie Ihre Indizierungsentscheidungen
Beim Erstellen benutzerdefinierter Module hinterlassen Sie einen kurzen Kommentar, der erklärt, warum ein Feld indiziert ist. Dies hilft zukünftigen Entwicklern und Beratern, die Absicht zu verstehen und zu vermeiden, den Index versehentlich während einer Umstrukturierung zu entfernen.
Häufige Fallstricke
Standardmäßig jedes Feld indizieren
Ein häufiger Fehler beim Lernen über Indizierung ist es, index=True zu jedem Feld hinzuzufügen, nur um auf der sicheren Seite zu sein. Das ist kontraproduktiv. Jedes Index benötigt Speicherplatz und erhöht den Aufwand für jede Schreiboperation. Bei Tabellen, die ein hohes Volumen an Einfügungen oder Aktualisierungen erhalten, können unnötige Indizes das System merklich verlangsamen.
Indizierung von Feldern in kleinen Tabellen
Bei Tabellen mit ein paar hundert Zeilen entscheidet der Abfrageplaner von PostgreSQL oft, dass ein sequenzieller Scan schneller ist als die Verwendung eines Index. Indizes beginnen, echten Nutzen zu bieten, wenn Tabellen auf Tausende von Datensätzen und mehr wachsen. Die Indizierung kleiner Nachschlagetabellen oder selten befüllter benutzerdefinierter Modelle fügt Komplexität hinzu, ohne einen praktischen Nutzen.
Vergessen, das Modul nach dem Hinzufügen von index=True zu aktualisieren
Das bloße Hinzufügen von index=True zu einer Felddefinition in Python erstellt nicht automatisch den Index in der Datenbank. Sie müssen das Modul mit -u module_name oder über das Odoo-Backend aktualisieren. Das Vergessen dieses Schrittes ist eine häufige Quelle der Verwirrung während der Entwicklung und kann zu Leistungsproblemen in Staging- oder Produktionsumgebungen führen, in denen das Upgrade übersprungen wurde.
Erwarten, dass Indizes ILIKE-Suchen auf Char-Feldern beschleunigen
Ein regulärer B-Baum-Index mit index=True hilft nicht bei ILIKE '%keyword%'-Abfragen, bei denen das Platzhalterzeichen am Anfang des Musters steht. PostgreSQL kann einen B-Baum-Index nicht verwenden, um ein führendes Platzhalterzeichen auszuwerten. Wenn Sie eine schnelle partielle Textsuche benötigen, verwenden Sie index='trigram' in Odoo 16+ oder erkunden Sie Optionen zur Volltextsuche.
Nicht Berücksichtigen von gespeicherten berechneten Feldern
Gespeicherte berechnete Felder (die mit store=True gekennzeichnet sind) haben eine Datenbankspalte und können indiziert werden. Entwickler übersehen dies manchmal und verpassen die Gelegenheit, die Leistung bei Feldern zu verbessern, die Werte aggregieren oder ableiten, die häufig in Filtern verwendet werden. Wenn ein gespeichertes berechnetes Feld in Domainfiltern über Berichte oder Ansichten erscheint, ist es wert, es zu indizieren.
Fazit
Das Attribut index=True ist ein kleines Detail in der Odoo-Felddefinition, hat jedoch einen echten Einfluss auf die Datenbankleistung, während Ihre Daten wachsen. Richtig eingesetzt, hält es die Suchen schnell, die Listenansichten reaktionsschnell und die Berichte schnell zu generieren. Sorglos verwendet, erhöht es den Aufwand ohne jeglichen Nutzen.
Die wichtigste Erkenntnis ist einfach: Indizieren Sie Felder, die regelmäßig in Domainfiltern verwendet werden, insbesondere Many2one-Felder in Modellen mit hohem Volumen. Folgen Sie den Mustern, die von Odoos eigenen Standardmodulen festgelegt wurden. Vermeiden Sie das Überindizieren kleiner Tabellen oder Felder, die niemals gefiltert werden. Und wenn Sie Odoo 16 oder später verwenden, ziehen Sie index='trigram' für Textsuchfelder in Betracht, in denen Benutzer partielle Zeichenfolgen eingeben.
Die richtige Indizierungsstrategie von Anfang an in einem benutzerdefinierten Entwicklungsprojekt festzulegen, ist viel einfacher, als später in der Produktion langsame Abfragen zu diagnostizieren.
Arbeiten Sie an einer Odoo-Implementierung?
Bei Dasolo helfen wir Unternehmen, Odoo zu implementieren, anzupassen und zu optimieren. Egal, ob Sie benutzerdefinierte Module erstellen, die Leistung einer bestehenden Instanz verbessern oder ein neues Odoo-Projekt von Grund auf planen, wir bringen praktische technische Expertise in jedes Engagement ein.
Wenn Sie mit langsamen Abfragen, komplexen Anpassungen zu tun haben oder Anleitung zu den besten Praktiken in der Odoo-Entwicklung benötigen, helfen wir Ihnen gerne weiter. Kontaktieren Sie das Dasolo-Team und lassen Sie uns wissen, woran Sie arbeiten.