Inleiding
Als u enige tijd heeft besteed aan het schrijven of beoordelen van Odoo-velddefinities, bent u waarschijnlijk iets tegengekomen zoals index=True op een veld. Het lijkt klein, bijna als een bijzaak. Maar dat enkele attribuut kan een betekenisvol verschil maken in hoe snel uw Odoo-instantie reageert wanneer gebruikers zoeken, filteren of navigeren door grote datasets.
Deze gids legt uit wat een geïndexeerd veld eigenlijk is in de context van het Odoo-datamodel, hoe het uw database beïnvloedt en wanneer het zinvol is om het te gebruiken in uw eigen Odoo-ontwikkelingswerk. Of u nu een aangepaste module bouwt of een bestaande implementatie beoordeelt, het begrijpen van dit concept zal u helpen betere beslissingen te nemen.
Wat is een geïndexeerd veld in Odoo
In de Odoo ORM wordt een veld als geïndexeerd verklaard wanneer de definitie index=True bevat. Dit vertelt Odoo om PostgreSQL te vragen een B-tree-index te maken op de overeenkomstige databasekolom wanneer de module wordt geïnstalleerd of bijgewerkt.
Hier is een eenvoudig voorbeeld van een Odoo-velddefinitie in Python:
class SaleOrder(models.Model):
_name = 'sale.order'
reference = fields.Char(string='Referentie', index=True)
state = fields.Selection([...], index=True)
partner_id = fields.Many2one('res.partner', index=True)
Vanuit een gebruikersinterfaceperspectief is er niets zichtbaar over geïndexeerde velden. Een gebruiker die een formulier invult of door een lijstweergave bladert, heeft geen manier om te weten of een veld geïndexeerd is of niet. De indexering is volledig een database-niveau kwestie.
Wat het beïnvloedt, is de snelheid. Wanneer een veld is geïndexeerd, kan PostgreSQL overeenkomende records veel sneller opzoeken, vooral in tabellen met duizenden of miljoenen rijen. Zonder een index moet de database elke rij in de tabel doorzoeken om de rijen te vinden die overeenkomen met uw zoekcriteria. Met een index navigeert het door een gestructureerde indeling en vindt het de resultaten direct.
Welke Odoo-veldtypen ondersteunen index=True
De meeste scalare veldtypen in de Odoo ORM ondersteunen de index eigenschap:
- Char en Text velden
- Integer en Float velden
- Date en Datetime velden
- Selection velden
- Many2one velden (zeer vaak geïndexeerd)
- Boolean velden
Relationele velden zoals One2many en Many2many hebben geen directe kolom om op dezelfde manier te indexeren, dus de index eigenschap is niet relevant voor hen. Gecomputeerde velden die niet zijn opgeslagen kunnen ook niet worden geïndexeerd, aangezien ze geen databasekolom hebben.
Hoe het veld werkt
Wanneer Odoo een module initialiseert of upgrade, leest het alle velddefinities en synchroniseert het de databaseschema. Voor elk veld met index=True voert Odoo een SQL-instructie uit om een index op die kolom in PostgreSQL te creëren.
Standaard maakt PostgreSQL een B-tree index aan, wat het standaard indextype is en goed werkt voor gelijkheidsvergelijkingen (=), bereikqueries (>, <, BETWEEN) en sorteren. Dit dekt de overgrote meerderheid van wat Odoo doet bij het filteren van records in lijstweergaven of het berekenen van domeingebaseerde zoekopdrachten.
Hoe het Interageert met de Odoo ORM
De Odoo ORM vertaalt Python domeinfilters naar SQL-query's. Wanneer je een domein schrijft zoals [('state', '=', 'sale')], genereert de ORM iets als WHERE state = 'sale'. Als het state veld een index heeft, gebruikt PostgreSQL deze om die voorwaarde efficiënt op te lossen zonder de hele tabel te scannen.
Many2one-velden zijn een zeer veelvoorkomend gebruiksgeval. In Odoo's datamodel slaat een veld zoals partner_id op een verkooporder de gehele ID van de gerelateerde partner op. Wanneer je de lijst van bestellingen opent die gefilterd zijn op klant, voert Odoo een query uit met een WHERE partner_id = X voorwaarde. Met een index op partner_id is die opzoeking snel, zelfs met honderdduizenden bestellingen in de database.
Indexen en Schrijfsnelheid
Indexen zijn niet gratis. Elke keer dat een record wordt aangemaakt, bijgewerkt of verwijderd, moet PostgreSQL alle indexen op die tabel ook bijwerken. Op tabellen met veel indexen duren schrijfoperaties iets langer. Voor de meeste Odoo-gebruiksscenario's is deze afweging het waard, maar het is belangrijk te begrijpen dat alles indexeren niet altijd het juiste antwoord is.
De index='trigram' Optie
In Odoo 16 en latere versies accepteert de index eigenschap niet alleen True maar ook de stringwaarde 'trigram'. Dit creëert een GIN trigram index met behulp van de pg_trgm PostgreSQL-extensie, die snelle patroonmatching ondersteunt met ILIKE query's. Dit is bijzonder nuttig voor tekstzoekopdrachten op velden zoals productnamen of partnernamen waar gebruikers vaak gedeeltelijke strings in de zoekbalk typen.
name = fields.Char(string='Productnaam', index='trigram')
Dit is een meer geavanceerde optie die wordt gebruikt in Odoo's eigen standaardmodules voor velden die vaak worden doorzocht op gedeeltelijke tekst.
Zakelijke gebruikscases
Geïndexeerde velden komen voor in veel echte Odoo-workflows. Hier zijn vijf praktische voorbeelden waarbij het indexeren van een veld een merkbaar verschil maakt.
1. CRM: Leads filteren op Verkoper
In CRM filteren sales managers regelmatig de pijplijn op verkoper. Het user_id veld op crm.lead is standaard geïndexeerd in Odoo, wat het filteren op verkoper snel maakt, zelfs met duizenden leads. Als je een aangepast Many2one-veld toevoegt dat naar een gebruiker of team verwijst, volgt het indexeren dezelfde logica.
2. Verkoop: Bestellingen zoeken op Status
Het state veld op sale.order is geïndexeerd. Dit maakt het snel laden van de lijst met bevestigde bestellingen, of het filteren op bestellingen die wachten op levering, mogelijk voor bedrijven die grote volumes verwerken. Selectievelden die vaak worden gebruikt als filtercriteria zijn goede kandidaten voor indexering.
3. Voorraad: Bewegingen volgen op Product
Voorraadbewegingen in Odoo kunnen zeer grote volumes bereiken, vooral in distributie- of productiebedrijven. Het product_id veld op stock.move is geïndexeerd, waardoor het efficiënt is om alle bewegingen voor een specifiek product op te vragen. Zonder deze index zouden producttraceerbaarheidrapporten pijnlijk traag worden in drukke magazijnen.
4. Boekhouding: Journaalposten filteren op Partner
Boekhouders openen vaak het grootboek voor een specifieke klant of leverancier. Het partner_id op account.move.line is geïndexeerd om die opzoekingen efficiënt te maken. In bedrijven met jaren aan boekhoudgeschiedenis is deze index wat ervoor zorgt dat het rapport over oude vorderingen niet tijdoverschrijdend wordt.
5. Aangepaste Modules: Referentievelden voor Traceerbaarheid
Bij het bouwen van aangepaste modules is het gebruikelijk om referentievelden toe te voegen die records over modellen heen koppelen, bijvoorbeeld een aangepaste projectcode of een extern documentnummer. Als gebruikers regelmatig op dat referentieveld zullen zoeken of filteren, is het toevoegen van index=True een eenvoudige manier om die zoekopdrachten snel te houden naarmate de data groeit.
Een geïndexeerd veld maken of aanpassen
In Python (Ontwikkeling van Aangepaste Modules)
Het toevoegen van index=True aan een velddefinitie in een Python-module is eenvoudig. Je voegt het gewoon toe als een sleutelwoordargument bij het declareren van het veld:
from odoo import models, fields
class ProjectTask(models.Model):
_inherit = 'project.task'
x_external_ref = fields.Char(
string='Externe Referentie',
index=True,
help='Referentienummer van het externe systeem'
)
Nadat je dit veld aan je module hebt toegevoegd, voer je odoo-bin -u your_module_name uit of upgrade je de module via het Apps-menu. Odoo zal het nieuwe veld detecteren en de bijbehorende index in de database aanmaken.
Je kunt ook een index aan een bestaand veld toevoegen door het te erven en de definitie te overschrijven, hoewel deze aanpak voorzichtigheid vereist om onbedoelde neveneffecten op het oorspronkelijke veldgedrag te vermijden.
In Odoo Studio
Odoo Studio stelt niet-technische gebruikers in staat om velden via de interface te creëren. Studio biedt echter momenteel geen optie om indexing in of uit te schakelen bij het creëren van velden. Velden die via Studio zijn gemaakt, worden in de database opgeslagen als handmatige velden en hebben standaard geen index=True ingesteld.
Als je een in Studio gemaakt veld om prestatie-redenen geïndexeerd wilt hebben, is de schoonste weg om de Studio-aanpassing om te zetten in een juiste Python-module en index=True in de code toe te voegen. Dit valt onder technische aanpassing en wordt doorgaans afgehandeld door een Odoo-ontwikkelaar in plaats van een Studio-gebruiker.
Een index rechtstreeks in PostgreSQL toevoegen
In sommige situaties, zoals bij het optimaliseren van een bestaande productie-database zonder een module-upgrade, kan een databasebeheerder een index rechtstreeks toevoegen met SQL:
CREATE INDEX CONCURRENTLY idx_sale_order_partner_id
ON sale_order (partner_id);
Het gebruik van CONCURRENTLY voorkomt het vergrendelen van de tabel tijdens het aanmaken van de index, wat belangrijk is in productieomgevingen. Dat gezegd hebbende, moet deze aanpak gecoördineerd worden met de Odoo-moduledefinitie om de Python-code en de database in sync te houden. Als de module later wordt geüpgraded, kan Odoo de index al dan niet beheren, afhankelijk van wat er in de velddefinitie staat.
Beste praktijken
Indexvelden die verschijnen in zoekdomeinen
Als een veld regelmatig wordt gebruikt in domeinfilters, hetzij in lijstweergavefilters, geautomatiseerde acties, geplande taken of afhankelijkheden van berekende velden, is het een goede kandidaat voor indexering. De meest voorkomende voorbeelden zijn Many2one-relationele velden, statusvelden en referentie- of codevelden.
Volg de Eigen Conventies van Odoo
De beste referentie voor wanneer index=True te gebruiken is de eigen broncode van Odoo. Kijk naar de standaard velddefinities in sale.order, account.move of stock.move om te zien welke velden de eigen ontwikkelaars van Odoo hebben gekozen om te indexeren. Die keuzes zijn gebaseerd op echte gebruikspatronen en prestatiegegevens van duizenden productiedatabases.
Indexeer Altijd Many2one Velden op Modellen met Hoge Volumes
Voor modellen die in de loop van de tijd een groot aantal records accumuleren (journalen, voorraadbewegingen, verkooporderregels), indexeer altijd Many2one-velden die worden gebruikt voor filtering. De kosten van een extra index op een schrijfintensieve tabel zijn bijna altijd de verbetering van de leesprestaties waard.
Overweeg Trigram Indexering voor Tekst Zoekvelden
Op Odoo 16 en later, als gebruikers vaak records zoeken door gedeeltelijke strings in te typen in een Char-veld zoals een productnaam, partnernaam of documentreferentie, overweeg dan om index='trigram' te gebruiken in plaats van de standaard B-tree index. Trigram-indexen zijn specifiek ontworpen voor ILIKE patroonmatching.
Controleer of Indexen Echt Worden Gebruikt
Na het toevoegen van een index, kun je verifiëren dat PostgreSQL deze gebruikt door een EXPLAIN ANALYZE op de query uit te voeren. Als de queryplanner nog steeds kiest voor een sequentiële scan, kan de tabel te klein zijn voor de index om voordelig te zijn, of de queryvoorwaarden zijn mogelijk niet compatibel met het type index.
Documenteer Je Indexeringsbeslissingen
Bij het bouwen van aangepaste modules, laat een korte opmerking achter die uitlegt waarom een veld is geïndexeerd. Dit helpt toekomstige ontwikkelaars en consultants de intentie te begrijpen en voorkomt dat de index per ongeluk wordt verwijderd tijdens een refactor.
Veelvoorkomende valkuilen
Indexeer Elk Veld Standaard
Een veelgemaakte fout bij het leren over indexering is om index=True aan elk veld toe te voegen, gewoon om zeker te zijn. Dit is contraproductief. Elke index neemt opslagruimte in beslag en voegt overhead toe aan elke schrijfoperatie. Op tabellen die een hoog volume aan invoegen of updates ontvangen, kunnen onnodige indexen het systeem merkbaar vertragen.
Indexeren van velden op kleine tabellen
Op tabellen met een paar honderd rijen besluit de queryplanner van PostgreSQL vaak dat een sequentiële scan sneller is dan het gebruik van een index. Indexen beginnen echte voordelen te bieden naarmate tabellen groeien naar duizenden records en meer. Het indexeren van kleine lookup-tabellen of zelden bevolkte aangepaste modellen voegt complexiteit toe zonder enige praktische voordelen.
Vergeten de module bij te werken na het toevoegen van index=True
Simpelweg index=True aan een velddefinitie in Python toe te voegen, creëert niet automatisch de index in de database. Je moet de module bijwerken met -u module_name of via de Odoo-backend. Het vergeten van deze stap is een veelvoorkomende bron van verwarring tijdens de ontwikkeling en kan leiden tot prestatieproblemen in staging- of productieomgevingen waar de upgrade werd overgeslagen.
Verwachten dat indexen ILIKE-zoekopdrachten op Char-velden versnellen
Een reguliere B-tree-index met index=True helpt niet bij ILIKE '%keyword%' zoekopdrachten waarbij het wildcard aan het begin van het patroon staat. PostgreSQL kan een B-tree-index niet gebruiken om een leidend wildcard te evalueren. Als je snelle gedeeltelijke tekstzoekopdrachten nodig hebt, gebruik dan index='trigram' op Odoo 16+ of verken de opties voor full-text search.
Geen rekening houden met opgeslagen berekende velden
Opgeslagen berekende velden (die store=True hebben) hebben wel een databasekolom en kunnen worden geïndexeerd. Ontwikkelaars vergeten dit soms en missen een kans om de prestaties te verbeteren op velden die waarden aggregeren of afleiden die veel worden gebruikt in filters. Als een opgeslagen berekend veld voorkomt in domeinfilters in rapporten of weergaven, is het de moeite waard om het te indexeren.
Conclusie
De index=True eigenschap is een klein detail in de Odoo-velddefinitie, maar het heeft een echte impact op de databaseprestaties naarmate je gegevens groeien. Correct gebruikt, houdt het zoekopdrachten snel, lijstweergaven responsief en rapporten snel te genereren. Onzorgvuldig gebruikt, voegt het overhead toe zonder enige voordelen.
De belangrijkste boodschap is eenvoudig: indexeer velden die regelmatig worden gebruikt in domeinfilters, vooral Many2one-velden op modellen met een hoog volume. Volg de patronen die zijn vastgesteld door de eigen standaardmodules van Odoo. Vermijd over-indexering van kleine tabellen of velden die nooit worden gefilterd. En als je op Odoo 16 of later bent, overweeg dan index='trigram' voor tekstzoekvelden waar gebruikers gedeeltelijke strings typen.
De indexeringsstrategie vanaf het begin van een aangepast ontwikkelingsproject goed krijgen, is veel gemakkelijker dan later trage zoekopdrachten in productie te diagnosticeren.
Werkt u aan een Odoo-implementatie?
Bij Dasolo helpen we bedrijven met de implementatie, aanpassing en optimalisatie van Odoo. Of je nu aangepaste modules bouwt, de prestaties van een bestaande instantie verbetert of een nieuw Odoo-project vanaf nul plant, wij brengen praktische technische expertise naar elke samenwerking.
Als je te maken hebt met trage queries, complexe aanpassingen, of begeleiding nodig hebt over de beste praktijken voor Odoo-ontwikkeling, helpen we je graag. Neem contact op met het Dasolo-team en laat ons weten waar je aan werkt.