sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL-index används inte för fråga om IP-intervall

Försök med ett index med flera kolumner, men med omvänd ordning i den andra kolumnen:

CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);

Beställning är för det mesta irrelevant för ett index med en kolumn, eftersom det kan skannas bakåt nästan lika snabbt. Men det är viktigt för index med flera kolumner.

Med det index jag föreslår kan Postgres skanna den första kolumnen och hitta adressen, där resten av indexet uppfyller det första villkoret. Sedan kan den, för varje värde i den första kolumnen, returnera alla rader som uppfyller det andra villkoret, tills den första misslyckas. Hoppa sedan till nästa värde i den första kolumnen osv.
Detta är fortfarande inte särskilt effektivt och Postgres kan vara snabbare bara genom att skanna den första indexkolumnen och filtrera efter den andra. Mycket beror på din datadistribution.

Hur som helst, CLUSTER genom att använda flerkolumnsindexet ovan kan hjälp prestanda:

CLUSTER ips USING index_ips_begin_end_ip_num

På så sätt packas kandidater som uppfyller ditt första villkor på samma eller intilliggande datasidor. Kan hjälpa prestanda mycket med om du har många rader per värde i den första kolumnen. Annars är det knappast effektivt.
(Det finns även icke-blockerande externa verktyg för ändamålet:pg_repack eller pg_squeeze.)

Dessutom körs och konfigureras autovacuum korrekt eller har du kört ANALYZE på bordet? Du behöver aktuell statistik för att Postgres ska kunna välja lämpliga frågeplaner.

Det som verkligen skulle hjälpa här är ett GiST-index för ett int8range kolumn, tillgänglig sedan PostgreSQL 9.2.

Mer läsning:

  • Optimera frågor på ett antal tidsstämplar (två kolumner)

Om dina IP-intervall kan täckas med en av de inbyggda nätverkstyperna inet eller cidr , överväg att ersätta dina två bigint kolumner. Eller ännu bättre, titta på tilläggsmodulen ip4r av Andrew Gierth (inte i standardfördelningen. Indexeringsstrategin ändras därefter.

Bortsett från det kan du kolla in det här relaterade svaret på dba.SE med att använda en sofistikerad regim med partiella index. Avancerade saker, men det ger fantastisk prestanda:

  • Kan rumsligt index hjälpa en "intervall - ordna efter - gräns"-fråga


  1. Maximal storlek för en SQL Server-fråga? IN-klausul? Finns det ett bättre tillvägagångssätt

  2. Hur man jämför två arrayer och väljer bara de icke-matchande elementen i postgres

  3. Hur man lagrar Emoji-tecken i MySQL-databasen

  4. Använder flera fält för en unik nyckel i Prisma