Как ускорить прохождение многоуровневого пути в 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:

размер кучи: начальный - 12 ГБ, максимум - 12 ГБ

кэш: 12 ГБ

Размер базы данных: 1,6 ГБ

Модель данных

Профиль запроса


person Rajendra Kadam    schedule 07.01.2019    source источник
comment
Этот план запроса бесполезен, если вы не развернете все элементы, чтобы показать, на какие значения действуют операторы. Кроме того, когда вы сказали, что используете подсказки сканирования, можете ли вы указать, что здесь было опробовано? Учитывая этот шаблон, вы можете увидеть, влияет ли производительность, начиная с начального или конечного узла шаблона.   -  person InverseFalcon    schedule 10.01.2019


Ответы (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 пути) , то шаблон пути переменной длины без верхней границы заставит neo4j проверить все эти исходящие пути. В этом случае, если вы все еще хотите использовать шаблон пути переменной длины, вам следует указать фиксированную верхнюю границу, поскольку вам известна точная длина интересующих путей (4, в этом примере):

MATCH path=(:A)-[:USE*..4]->(:E) RETURN path
person cybersam    schedule 07.01.2019
comment
Спасибо @cybersam за предложения. Я попробовал то, что вы предложили, я нашел тот же план запроса, потому что моя база данных больше похожа на дерево, начинающееся от A до E. - person Rajendra Kadam; 08.01.2019
comment
Я попробовал расширить путь apoc от E до C, время сократилось на 40-50%. Теперь я могу получить результат за 9 секунд. Использование запроса: MATCH (e: E) CALL apoc.path.expand (e, ‹USE, / C, 0,2) YIELD path AS p RETURN p - person Rajendra Kadam; 08.01.2019
comment
Как вы думаете, есть ли возможность улучшить это? Любое предложение ? - person Rajendra Kadam; 08.01.2019
comment
Вы пробовали MATCH path=(:C)-[:USE]->(:D)-[:USE]->(:E) RETURN path? - person cybersam; 08.01.2019
comment
Для метки C больше узлов, количество узлов типа C в десять раз больше, чем у E. - person Rajendra Kadam; 09.01.2019