PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Материализиран път на Postgres - Какви са ползите от използването на ltree?

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 ще спечели в този случай.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PG пълнотекстово търсене в релси, използвайки pg_search gem за подниз

  2. PostgreSQL - Получаване на статистически данни

  3. Опциите на падащия формуляр на Python, попълнени от sql

  4. Добавянето на колона като външен ключ дава ГРЕШКА колона, посочена в ограничението за външен ключ, не съществува

  5. Как да получите имена и типове на колони от PostgreSQL заявка (без да я стартирате)?