TL;DR Етикети за многократна употреба, сложни модели за търсене и търсене на родословие срещу множество наследствени възли (или единичен възел, чийто път все още не е извлечен) не могат да бъдат осъществени с помощта на материализиран индекс на път.
За тези, които се интересуват от кървавите подробности...
Първо, въпросът ви е уместен само ако не използвате повторно никакви етикети в описанието на вашия възел. Ако беше така, l-дървото наистина е единствената опция от двете. Но реализациите на материализирани пътища обикновено не се нуждаят от това, така че нека оставим това настрана.
Една очевидна разлика ще бъде в гъвкавостта на видовете търсения, които ви дава l-tree. Разгледайте тези примери (от ltree
документи, свързани във вашия въпрос):
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
Първата заявка очевидно е постижима с материализиран път. Последното също е постижимо, когато бихте коригирали заявката като търсене на брат или сестра. Средният случай обаче не е директно постижим с едно търсене в индекс. Ще трябва или да разделите това на две заявки (всички потомци + всички предшественици), или да прибегнете до сканиране на таблица.
И тогава има наистина сложни заявки като тази (също от документите):
Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain
Материализираният индекс на пътя би бил безполезен тук и ще е необходимо пълно сканиране на таблица, за да се справи с това. l-дървото е единствената опция, ако искате да изпълните това като SARGable заявка.
Но за стандартните йерархични операции намирането на някое от:
- родител
- деца
- потомци
- коренни възли
- листови възли
материализираният път ще работи също толкова добре, колкото l-дървото. Противно на статията, свързана по-горе , търсенето на всички потомци на общ прародител е много изпълнимо с помощта на b-дърво. Форматът на заявката WHERE path LIKE 'A.%'
е SARGable, при условие че вашият индекс е подготвен правилно (трябваше изрично да маркирам моя индекс на пътя с varchar_pattern_ops
за да работи това).
Това, което липсва в този списък, е намирането на всички предци за потомък. Форматът на заявката WHERE 'A.B.C.D' LIKE path || '.%'
за съжаление няма да използва индекса. Едно заобиколно решение, което прилагат някои библиотеки, е да анализират възлите на предшественика от пътя и да ги заявят директно:WHERE id IN ('A', 'B', 'C')
. Това обаче ще работи само ако се насочвате към предци на конкретен възел, чийто път вече сте извлекли. l-tree ще спечели в този случай.