Как ускорить прохождение многоуровневого пути в Neo4j
Я хочу найти все пути от конечного узла (E) до корневого узла (A). (Не для какого-либо конкретного узла, поэтому здесь нет идентификатора или фильтра)
Модель данных показана на рисунке.
Я использовал базовый запрос Cypher, чтобы найти пути (от A до E):
MATCH path=(:A)-[:USE*]->(:E) RETURN path
Он продолжает работать и никогда не заканчивается.
Я попытался получить пути от C до E, используя:
MATCH path=(:C)-[:USE*]->(:E) RETURN path
Этот запрос занимает до 18 секунд, чтобы вернуть 18 тыс. Путей. Я пытался использовать сканирование, но никаких улучшений в то время.
Как я могу улучшить этот обход, чтобы вернуть результаты за меньшее время? Мне нужно получить результаты через 4-5 секунд.
Конфигурации системы:
Системная память 32 ГБ
Хранение: SSD
Текущий Neo4j Conf:
размер кучи: начальный-12GB макс-12GB
кэш: 12 ГБ
Размер базы данных: 1,6 ГБ
1 ответ
Если ваши пути БД имеют много вариантов (например, C
узлы не всегда сопровождаются D
узлы), но вы знаете, что вы всегда хотите определенный шаблон пути (например, A->B->C->D->E
), тогда указание явного шаблона должно быть намного быстрее:
MATCH path=(:A)-[:USE]->(:B)-[:USE]->(:C)-[:USE]->(:D)-[:USE]->(:E)
RETURN path
Шаблоны пути переменной длины дороги, поскольку имеют экспоненциальную сложность (в зависимости от глубины пути).
[ОБНОВИТЬ]
Даже когда интересующие вас пути к БД не имеют никакой изменчивости (например, путь от A
в E
всегда выглядит как A->B->C->D->E
), но есть более длинные пути, которые включают эти пути (например, если E
узлы имеют длинные исходящие USE
paths), тогда шаблон пути переменной длины без верхней границы заставит neo4j протестировать все эти исходящие пути. В этом случае, если вы все еще хотите использовать шаблон пути переменной длины, вам следует указать фиксированную верхнюю границу, поскольку вы знаете точную длину интересующих путей (4
в этом примере):
MATCH path=(:A)-[:USE*..4]->(:E) RETURN path