sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres Materialized Path - Vilka är fördelarna med att använda ltree?

TL;DR Återanvändbara etiketter, komplexa sökmönster och härkomstsökningar mot flera efterkommande noder (eller en enda nod vars sökväg ännu inte har hämtats) kan inte utföras med ett materialiserat sökvägsindex.

För den som är intresserad av de blodiga detaljerna...

För det första är din fråga endast relevant om du inte återanvänder några etiketter i din nodbeskrivning. Om du var det, är l-trädet egentligen det enda alternativet av de två. Men materialiserade sökvägsimplementeringar behöver vanligtvis inte detta, så låt oss lägga det åt sidan.

En uppenbar skillnad kommer att vara i flexibiliteten i de typer av sökningar som l-tree ger dig. Betrakta dessa exempel (från ltree dokument länkade i din fråga):

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

Den första frågan är uppenbarligen möjlig med materialiserad sökväg. Det sista är också möjligt, där du skulle justera frågan som en syskonsökning. Mellanfallet är dock inte direkt möjligt med en enda indexuppslagning. Du måste antingen dela upp detta i två frågor (alla ättlingar + alla förfäder), eller ta till en tabellskanning.

Och sedan finns det riktigt komplexa frågor som den här (också från dokumenten):

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

Ett materialiserat sökvägsindex skulle vara värdelöst här, och en fullständig tabellskanning skulle krävas för att hantera detta. l-tree är det enda alternativet om du vill utföra detta som en SARG-förfrågan.

Men för de vanliga hierarkiska operationerna, hitta något av:

  • förälder
  • barn
  • ättlingar
  • rotnoder
  • lövnoder

materialiserad väg kommer att fungera lika bra som l-träd. I motsats till artikeln länkad ovan , att söka efter alla ättlingar till en gemensam förfader är mycket genomförbart med ett b-träd. Frågeformatet WHERE path LIKE 'A.%' är SARGable förutsatt att ditt index är förberett ordentligt (jag var tvungen att uttryckligen tagga mitt sökvägsindex med varchar_pattern_ops för att få det här att fungera).

Det som saknas på den här listan är att hitta alla förfäder för en ättling. Frågeformatet WHERE 'A.B.C.D' LIKE path || '.%' kommer tyvärr inte att använda indexet. En lösning som vissa bibliotek implementerar är att analysera förfädernoderna från sökvägen och fråga dem direkt:WHERE id IN ('A', 'B', 'C') . Detta kommer dock bara att fungera om du riktar in dig på förfäder till en specifik nod vars sökväg du redan har hämtat. l-tree kommer att vinna på den här.




  1. Anslut till SphinxQL via Linux kommandorad

  2. sql server 2008 management studio kontrollerar inte syntaxen för min fråga

  3. Doctrine querybuilder DATE_FORMAT fungerar inte

  4. Hur man bäst delar csv-strängar i oracle 9i