Innledning
Når du gransker Odoo-felter i kodebasen, støter du ofte på index=True — en tilsynelatende liten parameter som kan ha stor betydning for søke- og filtreringshastigheten i en database med mange poster.
Denne guiden forklarer hva et indeksfelt innebærer i Odoo sitt datamodell-perspektiv, hvordan det påvirker PostgreSQL-databasen, og når det gir mening å bruke det i dine egne moduler eller endringer. Kunnskap om dette gjør det enklere å ta velbegrunnede tekniske beslutninger.
Hva betyr det at et felt er indeksert i Odoo?
I Odoo sin ORM angir index=True i feltdefinisjonen at systemet skal be PostgreSQL opprette en indeks (vanligvis B-tree) for den underliggende kolonnen når modulen installeres eller oppdateres.
Et enkelt eksempel fra en Python-feltdefinisjon viser hvordan man legger til indeksering i praksis.
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)
Fra brukerens ståsted er indeksering usynlig — skjemaer og listesider viser ingen merkelapp som sier «indeksert». Endringen skjer på databasenivå og berører kun hvordan PostgreSQL finner poster.
Effekten handler først og fremst om ytelse. En indeks gjør oppslag mot store tabeller mye raskere ved å la databasen navigere en sortert struktur i stedet for å lese hver enkelt rad. Uten indeks må databasen ofte gjøre full tabellskanning for å finne treff.
Hvilke Odoo-felttyper kan indekseres
De fleste enkle (skalare) felttypene i Odoo støtter indeksering ved å bruke index-argumentet:
- Char og Text-felt
- Integer og Float-felt
- Date og Datetime-felt
- Selection-felt
- Many2one-felt (ofte indeksert som standard)
- Boolean-felt
Relasjoner som One2many og Many2many har ikke en enkel kolonne å indekseres på samme måte, så index er ikke relevant der. Beregnede felt som ikke er lagret i databasen kan heller ikke indekseres.
Hvordan fungerer et indeksfelt
Når Odoo starter opp eller oppgraderer en modul, synkroniserer det feltene mot databasen. For felt med index=True sender Odoo SQL for å opprette den nødvendige indeksen i PostgreSQL.
Standardindeksen i PostgreSQL er en B-tree, som fungerer godt for likhetsoperasjoner (=), intervallspørringer (>, <, BETWEEN) og sortering — det dekker de fleste Odoo-filtre og domainsøk.
Hvordan Odoo ORM drar nytte av indekser
ORM-en oversetter Python-domener til SQL. Et domenesøk som [('state', '=', 'sale')] blir til en WHERE-klausul i SQL. Har feltet en indeks, kan PostgreSQL bruke den for å finne treff uten å skanne hele tabellen.
Et vanlig eksempel er Many2one-felt. Feltet partner_id lagrer en heltallsreferanse til en kunde, og spørringer som WHERE partner_id = X blir betydelig raskere når kolonnen er indeksert, selv med hundretusener av ordre.
Indekser og skriveoperasjoner
Indeksering kommer med kostnad: hver INSERT, UPDATE eller DELETE må også oppdatere alle indekser på tabellen. For tabeller med mange indekser gir dette ekstra skrivekostnad, så blindt å indeksere alt er ofte uheldig.
Alternativet index='trigram'
Fra Odoo 16 kan index også settes til 'trigram', som ber PostgreSQL om å bruke en GIN trigram-indeks (krever pg_trgm-utvidelsen). Denne er laget for raske mønstersøk med ILIKE og partial matching.
name = fields.Char(string='Product Name', index='trigram')
Trigram er et bevisst valg i standardmoduler for felt der brukere ofte søker med delvise eller unøyaktige tekststrenger.
Reelle forretningsscenarier
Her er noen praktiske situasjoner der indeksering gir tydelig ytelsesgevinst i ekte Odoo-miljøer.
1. CRM: Filtrering av leads på ansvarlig selger
I CRM filtrerer ledere pipeline etter ansvarlig bruker. Feltet user_id på crm.lead er vanligvis indeksert for å holde slike filtre raske selv ved mange tusen leads. Samme prinsipp gjelder for egendefinerte Many2one-felt mot bruker eller team.
2. Salg: Søk etter ordre etter status
Statusfelt på ordre (f.eks. state på sale.order) er indeksert i standarden for å muliggjøre raske filtreringer—viktig for bedrifter med høyt ordrevvolum som filtrerer på bekreftet, levert eller fakturert.
3. Lager: Sporing av bevegelser per produkt
I lagerstyring vokser poster raskt. Å indeksere product_id på stock.move gjør det mulig å hente alle bevegelser for et produkt uten store forsinkelser i rapporter og sporbarhet.
4. Regnskap: Åpne bilag per partner
Regnskapsbrukere leter ofte opp bilag for spesifikke kunder eller leverandører. Et indeksert partner_id på bilagslinjer gjør slike søk håndterbare selv med mange års regnskapsdata.
5. Egendefinerte moduler: Referansefelt for sporbarhet
Når du lager egne løsninger er det vanlig å legge til referanse- eller kodenummerfelt som brukes i søk eller rapporter. Hvis feltet skal være et regelmessig filter, er index=True en enkel og effektiv løsning.
Slik oppretter eller tilpasser du et indeksfelt
I Python (ved utvikling av moduler)
Det er enkelt å legge til index=True i feltdeklarasjonen i en Python-modul ved å sende argumentet når feltet defineres.
from odoo import models, fields
class ProjectTask(models.Model):
_inherit = 'project.task'
x_external_ref = fields.Char(
string='External Reference',
index=True,
help='Reference number from the external system'
)
Etter å ha lagt til feltet må du oppdatere modulen (f.eks. odoo-bin -u your_module_name eller via Apps) slik at Odoo oppretter indeksen i databasen.
Du kan også overstyre et eksisterende felt for å legge til indeksering, men dette krever forsiktighet for å unngå utilsiktede endringer i feltets oppførsel.
I Odoo Studio
Odoo Studio gjør det lett for ikke-tekniske brukere å opprette felt via UI, men Studio tilbyr vanligvis ikke en innstilling for å sette index=True. Felt opprettet i Studio får ikke indeks automatisk.
Hvis et Studio-felt trenger indeksering av ytelsesårsaker, er den ryddigste løsningen å konvertere til en ekte Python-modul og legge inn index=True, noe som vanligvis gjøres av en utvikler.
Opprette indeks direkte i PostgreSQL
I noen situasjoner, for eksempel ved ytelsesoptimalisering i produksjon uten moduloppgradering, kan en DBA opprette indeksen manuelt med SQL.
CREATE INDEX CONCURRENTLY idx_sale_order_partner_id
ON sale_order (partner_id);
Bruk av CONCURRENTLY unngår låsing av tabellen under indeksskaping — viktig i produksjon. Samtidig bør slike endringer koordineres med Odoo-koden slik at definisjonen forblir konsistent ved senere oppgraderinger.
Gode praksiser for indeksering
Indekser for felter som brukes i søkedomener
Hvis et felt ofte brukes i domains — i filter på lister, automatiske handlinger, eller bakgrunnsjobber — er det en god kandidat for indeksering. Typiske eksempler er Many2one-felt, statusfelt og referansefelt.
Følg Odoos egne valg som veiviser
En praktisk regel er å se hva Odoo selv indekserer i standardmodulene som sale.order, account.move eller stock.move. Valgene i standardkodene reflekterer reelle bruksområder og erfaringer fra produksjonssystemer.
Indekser alltid Many2one på store modeller
På modeller som vokser mye over tid (bilagslinjer, lagerbevegelser, salgsordrer) bør Many2one-felter som brukes til filtrering nesten alltid indekseres. Gevinsten i lesehastighet veier som regel opp for den lille skrivekostnaden.
Vurder trigram for tekstsøk
I Odoo 16+ bør du vurdere index='trigram' for Char-felt der brukerne søker med delstrenger, som produktnavn eller kundesøk — trigram gir bedre ytelse for ILIKE-søking.
Sjekk at indeksen faktisk brukes
Etter å ha lagt til en indeks bør du kjøre EXPLAIN ANALYZE for å forsikre deg om at PostgreSQL-planner velger indeksen. For små tabeller eller upraktiske spørringsmønstre kan planleggeren fortsatt velge sekvensiell skanning.
Dokumenter hvorfor du indekserer
Legg igjen korte kommentarer i koden eller dokumentasjonen om hvorfor et felt er indeksert. Det hjelper fremtidige utviklere å forstå motivet og reduserer risikoen for at indeksen fjernes ved et uhell.
Vanlige fallgruver
Indeksering av alle felter som standard
En vanlig feil er å sette index=True på alle felt «for sikkerhets skyld». Det fører til unødvendig lagringsbruk og merkbar skrivekostnad på hyppig oppdaterte tabeller — altså motsatt av målet.
Indekser på små tabeller
På små tabeller med få hundre rader er sekvensiell skanning ofte raskere enn å bruke en indeks. Indekser blir først nyttige når datasettene vokser til tusener av rader eller mer.
Glemme moduloppgradering etter å ha lagt til index=True
Å skrive index=True i Python uten å oppgradere modulen gjør ikke indeksen i databasen. Husk å kjøre moduloppgradering — manglende oppgradering er en vanlig årsak til at forventet ytelsesforbedring uteblir.
Forvente at B-tree hjelper ILIKE med ledende wildcard
En vanlig misforståelse er at en vanlig B-tree-indeks hjelper på ILIKE '%søkeord%'. Det gjør den ikke. For ledende wildcard må du bruke trigram eller fulltekstsøk for god ytelse.
Overser lagrede beregnede felt
Beregnete felt som er lagret (store=True) har fysisk kolonne og kan indekseres. Dette blir noen ganger oversett — men dersom slike felt brukes i rapporter eller filtre er indeksering ofte en god idé.
Oppsummering
Selv om index=True virker som en liten detalj, påvirker det hvordan søk skalerer når datamengdene vokser. Riktig bruk holder lister og rapporter raske; feil bruk gir unødvendig overhead.
Kort sagt: indekser felter som brukes ofte i domains, spesielt Many2one på store tabeller. Følg Odoos egne mønstre, unngå overindeksering på små eller sjeldent filteerte felter, og vurder index='trigram' for deltekst-søk på Odoo 16+.
Å legge en god indekseringsstrategi tidlig i et utviklingsprosjekt er langt enklere enn å feilsøke trege spørringer i et produksjonssystem senere.
Jobber du med en Odoo-implementering?
Hos Dasolo hjelper vi bedrifter med å implementere, tilpasse og optimalisere Odoo. Enten det gjelder utvikling av moduler, ytelsesforbedringer eller å planlegge en ny Odoo-løsning, bidrar vi med praktisk teknisk kompetanse.
Har du problemer med trege spørringer, komplekse tilpasninger eller trenger råd om beste praksis i Odoo-utvikling, kan vi bistå. Ta kontakt med Dasolo-teamet og fortell oss hva du jobber med.