TL;DR Etykiety wielokrotnego użytku, złożone wzorce wyszukiwania i wyszukiwania przodków w wielu węzłach potomnych (lub pojedynczym węźle, którego ścieżka nie została jeszcze pobrana) nie mogą być wykonane przy użyciu zmaterializowanego indeksu ścieżki.
Dla zainteresowanych krwawymi szczegółami...
Po pierwsze, twoje pytanie jest istotne tylko wtedy, gdy nie używasz ponownie żadnych etykiet w opisie węzła. Jeśli tak, l-drzewo jest naprawdę jedyną opcją z tych dwóch. Ale implementacje zmaterializowanych ścieżek zazwyczaj tego nie potrzebują, więc odłóżmy to na bok.
Jedną z oczywistych różnic będzie elastyczność w typach wyszukiwań, które zapewnia l-tree. Rozważ te przykłady (z ltree
dokumenty, do których prowadzą linki w Twoim pytaniu):
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
Pierwsze zapytanie jest oczywiście osiągalne ze zmaterializowaną ścieżką. Ostatni jest również osiągalny, gdzie można dostosować zapytanie jako wyszukiwanie rodzeństwa. Jednak środkowy przypadek nie jest bezpośrednio osiągalny za pomocą pojedynczego wyszukiwania indeksu. Musisz albo podzielić to na dwa zapytania (wszyscy potomkowie + wszyscy przodkowie), albo uciec się do skanowania tabeli.
A potem są naprawdę złożone zapytania, takie jak to (również z dokumentacji):
Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain
Zmaterializowany indeks ścieżki byłby tutaj bezużyteczny, a do obsługi tego byłoby wymagane pełne skanowanie tabeli. l-tree jest jedyną opcją, jeśli chcesz wykonać to jako zapytanie SARGable.
Ale w przypadku standardowych operacji hierarchicznych można znaleźć dowolne z:
- rodzic
- dzieci
- potomkowie
- węzły główne
- węzły liści
zmaterializowana ścieżka będzie działać tak samo dobrze jak l-drzewo. W przeciwieństwie do artykułu, do którego link znajduje się powyżej , wyszukiwanie wszystkich potomków wspólnego przodka jest bardzo wykonalne przy użyciu b-drzewa. Format zapytania WHERE path LIKE 'A.%'
jest SARGable pod warunkiem, że twój indeks jest przygotowany poprawnie (musiałem wyraźnie oznaczyć mój indeks ścieżki za pomocą varchar_pattern_ops
aby to zadziałało).
To, czego brakuje na tej liście, to znalezienie wszystkich przodków dla potomka. Format zapytania WHERE 'A.B.C.D' LIKE path || '.%'
niestety nie będzie korzystał z indeksu. Jednym z obejść, które implementują niektóre biblioteki, jest przeanalizowanie węzłów przodków ze ścieżki i bezpośrednie zapytanie:WHERE id IN ('A', 'B', 'C')
. Jednak będzie to działać tylko wtedy, gdy celujesz w przodków określonego węzła, którego ścieżkę już pobrałeś. W tym przypadku wygra l-drzewo.