PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL-Index wird nicht für die Abfrage von IP-Bereichen verwendet

Versuchen Sie es mit einem mehrspaltigen Index, aber mit umgekehrter Reihenfolge in der zweiten Spalte:

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

Bei einem einspaltigen Index ist die Reihenfolge meist irrelevant, da er fast genauso schnell rückwärts durchsucht werden kann. Aber es ist wichtig für mehrspaltige Indizes.

Mit dem von mir vorgeschlagenen Index kann Postgres die erste Spalte scannen und die Adresse finden, bei der der Rest des Index die erste Bedingung erfüllt. Dann kann es für jeden Wert der ersten Spalte alle Zeilen zurückgeben, die die zweite Bedingung erfüllen, bis die erste fehlschlägt. Dann zum nächsten Wert der ersten Spalte springen usw.
Das ist immer noch nicht sehr effizient und Postgres kann schneller sein, indem Sie einfach die erste Indexspalte scannen und nach der zweiten filtern. Sehr viel hängt von Ihrer Datenverteilung ab.

So oder so, CLUSTER mit dem mehrspaltigen Index von oben kann Hilfeleistung:

CLUSTER ips USING index_ips_begin_end_ip_num

Auf diese Weise werden Kandidaten, die Ihre erste Bedingung erfüllen, auf dieselbe oder benachbarte Datenseiten gepackt. Kann die Leistung erheblich verbessern, wenn Sie viele Zeilen pro Wert der ersten Spalte haben. Sonst ist es kaum effektiv.
(Es gibt auch nicht blockierende externe Tools für diesen Zweck:pg_repack oder pg_squeeze.)

Außerdem läuft die Selbstbereinigung und ist richtig konfiguriert oder haben Sie ANALYZE ausgeführt auf dem Tisch? Sie benötigen aktuelle Statistiken, damit Postgres geeignete Abfragepläne auswählen kann.

Was hier wirklich helfen würde, wäre ein GiST-Index für einen int8range Spalte, verfügbar seit PostgreSQL 9.2.

Weiterführende Literatur:

  • Optimieren von Abfragen für eine Reihe von Zeitstempeln (zwei Spalten)

Wenn Ihre IP-Bereiche können mit einem der eingebauten Netzwerktypen inet abgedeckt werden oder cidr , erwägen Sie, Ihre beiden bigint zu ersetzen Säulen. Oder, noch besser, schauen Sie sich das Zusatzmodul ip4r an von Andrew Gierth (nicht in der Standarddistribution. Die Indizierungsstrategie ändert sich entsprechend.

Abgesehen davon können Sie diese verwandte Antwort auf dba.SE mit einem ausgeklügelten Regime mit Teilindizes überprüfen. Fortgeschrittenes Zeug, aber es liefert großartige Leistung:

  • Kann der räumliche Index bei einer „Range – Order by – Limit“-Abfrage helfen