TL;DR Rótulos reutilizáveis, padrões de pesquisa complexos e pesquisas de ancestralidade em vários nós descendentes (ou um único nó cujo caminho ainda não foi recuperado) não podem ser realizados usando um índice de caminho materializado.
Para os interessados nos detalhes sangrentos...
Em primeiro lugar, sua pergunta só é relevante se você não estiver reutilizando nenhum rótulo na descrição do nó. Se fosse, a l-tree é realmente a única opção das duas. Mas as implementações de caminho materializado normalmente não precisam disso, então vamos deixar isso de lado.
Uma diferença óbvia será a flexibilidade nos tipos de buscas que o l-tree oferece. Considere estes exemplos (do
ltree
docs vinculados em sua pergunta):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
A primeira consulta é obviamente alcançável com o caminho materializado. O último também é possível, onde você ajusta a consulta como uma pesquisa de irmãos. O caso do meio, no entanto, não é diretamente alcançável com uma única pesquisa de índice. Você teria que dividir isso em duas consultas (todos os descendentes + todos os ancestrais) ou recorrer a uma varredura de tabela.
E então existem consultas realmente complexas como esta (também dos documentos):
Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain
Um índice de caminho materializado seria inútil aqui, e uma varredura completa da tabela seria necessária para lidar com isso. l-tree é a única opção se você quiser fazer isso como uma consulta SARGable.
Mas para as operações hierárquicas padrão, encontrar qualquer um dos seguintes:
- pai
- crianças
- descendentes
- nós raiz
- nós de folha
caminho materializado funcionará tão bem quanto l-tree. Ao contrário do artigo vinculado acima , procurar todos os descendentes de um ancestral comum é muito factível usando uma b-tree. O formato de consulta
WHERE path LIKE 'A.%'
é SARGable desde que seu índice esteja preparado corretamente (eu tive que marcar explicitamente meu índice de caminho com varchar_pattern_ops
para fazer isso funcionar). O que está faltando nesta lista é encontrar todos os ancestrais para um descendente. O formato de consulta
WHERE 'A.B.C.D' LIKE path || '.%'
infelizmente não vai usar o índice. Uma solução que algumas bibliotecas implementam é analisar os nós ancestrais do caminho e consultá-los diretamente:WHERE id IN ('A', 'B', 'C')
. No entanto, isso só funcionará se você estiver segmentando ancestrais de um nó específico cujo caminho você já recuperou. l-tree vai ganhar neste.