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

Postgres Materialized Path - Welche Vorteile hat die Verwendung von ltree?

TL;DR Wiederverwendbare Labels, komplexe Suchmuster und Abstammungssuchen für mehrere untergeordnete Knoten (oder einen einzelnen Knoten, dessen Pfad noch nicht abgerufen wurde) können nicht mit einem materialisierten Pfadindex erreicht werden.

Für diejenigen, die an den blutigen Details interessiert sind...

Erstens ist Ihre Frage nur relevant, wenn Sie in Ihrer Knotenbeschreibung keine Beschriftungen wiederverwenden. Wenn ja, ist der L-Baum wirklich die einzige Option der beiden. Aber materialisierte Pfadimplementierungen brauchen dies normalerweise nicht, also lassen wir das beiseite.

Ein offensichtlicher Unterschied liegt in der Flexibilität bei den Suchtypen, die l-tree Ihnen bietet. Betrachten Sie diese Beispiele (aus dem ltree in Ihrer Frage verlinkte Dokumente):

foo         Match the exact label path foo
*.foo.*     Match any label path containing the label foo
*.foo       Match any label path whose last label is foo

Die erste Abfrage ist offensichtlich mit materialisiertem Pfad erreichbar. Letzteres ist auch möglich, wo Sie die Abfrage als Geschwistersuche anpassen würden. Der mittlere Fall ist jedoch nicht direkt mit einer einzigen Indexsuche erreichbar. Sie müssten dies entweder in zwei Abfragen aufteilen (alle Nachkommen + alle Vorfahren) oder auf einen Tabellenscan zurückgreifen.

Und dann gibt es wirklich komplexe Abfragen wie diese (ebenfalls aus der Dokumentation):

Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain

Ein materialisierter Pfadindex wäre hier nutzlos, und ein vollständiger Tabellenscan wäre erforderlich, um dies zu handhaben. l-tree ist die einzige Option, wenn Sie dies als SARG-fähige Abfrage ausführen möchten.

Aber für die hierarchischen Standardoperationen finden Sie eine der folgenden:

  • Elternteil
  • Kinder
  • Nachkommen
  • Stammknoten
  • Blattknoten

Der materialisierte Pfad funktioniert genauso gut wie l-tree. Im Gegensatz zu dem oben verlinkten Artikel , ist die Suche nach allen Nachkommen eines gemeinsamen Vorfahren mit einem b-Baum sehr gut machbar. Das Abfrageformat WHERE path LIKE 'A.%' ist SARGable, vorausgesetzt, Ihr Index ist richtig vorbereitet (ich musste meinen Pfadindex explizit mit varchar_pattern_ops taggen um dies zum Laufen zu bringen).

Was in dieser Liste fehlt, ist das Finden aller Vorfahren für einen Nachkommen. Das Abfrageformat WHERE 'A.B.C.D' LIKE path || '.%' wird den Index leider nicht verwenden. Eine Problemumgehung, die einige Bibliotheken implementieren, besteht darin, die Vorgängerknoten aus dem Pfad zu analysieren und sie direkt abzufragen:WHERE id IN ('A', 'B', 'C') . Dies funktioniert jedoch nur, wenn Sie auf Vorfahren eines bestimmten Knotens abzielen, dessen Pfad Sie bereits abgerufen haben. l-tree wird hier gewinnen.