Prøv et indeks med flere kolonner, men med omvendt rækkefølge i anden kolonne:
CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);
Bestilling er for det meste irrelevant for et enkelt-kolonne indeks, da det næsten lige så hurtigt kan scannes baglæns. Men det er vigtigt for indekser med flere kolonner.
Med det indeks, jeg foreslår, kan Postgres scanne den første kolonne og finde adressen, hvor resten af indekset opfylder den første betingelse. Så kan den for hver værdi i den første kolonne returnere alle rækker, der opfylder den anden betingelse, indtil den første fejler. Spring derefter til den næste værdi i den første kolonne osv.
Dette er stadig ikke særlig effektivt og Postgres kan være hurtigere bare at scanne den første indekskolonne og filtrere efter den anden. Meget afhænger af din datadistribution.
Uanset hvad, CLUSTER
ved at bruge multikolonneindekset ovenfra kan hjælpe ydeevne:
CLUSTER ips USING index_ips_begin_end_ip_num
På denne måde pakkes kandidater, der opfylder din første betingelse, på de samme eller tilstødende datasider. Kan hjælpe ydeevnen meget med, hvis du har mange rækker pr. værdi af den første kolonne. Ellers er det næppe effektivt.
(Der er også ikke-blokerende eksterne værktøjer til formålet:pg_repack eller pg_squeeze.)
Kører autovakuum og er konfigureret korrekt, eller har du kørt ANALYZE
på bordet? Du skal bruge aktuelle statistikker for at Postgres kan vælge passende forespørgselsplaner.
Det, der virkelig ville hjælpe her, er et GiST-indeks for et int8range
kolonne, tilgængelig siden PostgreSQL 9.2.
Yderligere læsning:
- Optimering af forespørgsler på en række tidsstempler (to kolonner)
Hvis dine IP-områder kan dækkes med en af de indbyggede netværkstyper inet
eller cidr
, overveje at erstatte dine to bigint
kolonner. Eller endnu bedre, se til det ekstra modul ip4r af Andrew Gierth (ikke i standardfordelingen. Indekseringsstrategien ændres i overensstemmelse hermed.
Bortset fra det, kan du tjekke dette relaterede svar på dba.SE med at bruge et sofistikeret regime med delvise indekser. Avancerede ting, men det giver fantastisk ydeevne:
- Kan rumlig indeks hjælpe en "range - order by - limit"-forespørgsel