В ответ на вопрос "Neo4j Cypher находит медленный путь в ненаправленном график". Майкл Хангер и Уэс Фриман любезно помогли, но мне не удалось адаптировать изученные методы к запросам поиска путей, которые должны возвращать пути.
Проблема:
Приведенный ниже запрос занимает примерно 3 секунды и возвращает 13 строк (найденные пути) из базы данных. Я нахожу его медленным и хотел бы, чтобы он выполнялся быстрее, но не знаю, как его оптимизировать. (Конечно, это пример, но я также нахожу подобные запросы медленными.)
START n=node:NodeIds('id:4000'), t=node:NodeIds('id:10778')
MATCH path = (n)-[:ASSOCIATIVY_CONNECTION*1..3]-(t)
RETURN nodes(path) AS Nodes
И то же самое с данными профиля:
neo4j-sh (0)$ profile START n=node:NodeIds('id:4000'), t=node:NodeIds('id:10778') MATCH path = (n)-[:ASSOCIATIVY_CONNECTION*1..3]-(t) RETURN nodes(path) AS Nodes;
==> +-------------------------------------------------------------------------------------------+
==> | Nodes |
==> +-------------------------------------------------------------------------------------------+
==> | [Node[3984]{Id:4000},Node[986]{Id:1001},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[1085]{Id:1100},Node[9955]{Id:9970},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[133348]{Id:133364},Node[9955]{Id:9970},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[111409]{Id:111425},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[64464]{Id:64480},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[64464]{Id:64480},Node[9955]{Id:9970},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[64464]{Id:64480},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[64464]{Id:64480},Node[64455]{Id:64471},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[79152]{Id:79168},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[69190]{Id:69206},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[25893]{Id:25909},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[31683]{Id:31699},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> | [Node[3984]{Id:4000},Node[6965]{Id:6980},Node[18536]{Id:18552},Node[10763]{Id:10778}] |
==> +-------------------------------------------------------------------------------------------+
==> 13 rows
==> 2824 ms
==>
==> ColumnFilter(symKeys=["path", "n", "t", " UNNAMED3", "Nodes"], returnItemNames=["Nodes"], _rows=13, _db_hits=0)
==> Extract(symKeys=["n", "t", " UNNAMED3", "path"], exprKeys=["Nodes"], _rows=13, _db_hits=0)
==> ExtractPath(name="path", patterns=[" UNNAMED3=n-[:ASSOCIATIVY_CONNECTION*1..3]-t"], _rows=13, _db_hits=0)
==> PatternMatch(g="(n)-[' UNNAMED3']-(t)", _rows=13, _db_hits=0)
==> Nodes(name="t", _rows=1, _db_hits=1)
==> Nodes(name="n", _rows=1, _db_hits=1)
==> ParameterPipe(_rows=1, _db_hits=0)
Настройка:
База данных графа Neo4j имеет 165 тыс. узлов и 266 тыс. отношений, где все отношения являются ненаправленными (двунаправленными) и имеют метку «ASSOCIATIVY_CONNECTION». Ни один из узлов не подключен к корневому узлу. Помимо узлов и отношений, для каждого узла хранится только одно целочисленное значение (база данных графа используется не для хранения фактических данных, а только для структуры).
Конфигурация памяти для этой базы данных следующая:
wrapper.java.initmemory=1024
wrapper.java.maxmemory=1024
neostore.nodestore.db.mapped_memory=225M
neostore.relationshipstore.db.mapped_memory=250M
neostore.propertystore.db.mapped_memory=290M
neostore.propertystore.db.strings.mapped_memory=330M
neostore.propertystore.db.arrays.mapped_memory=330M
Набор данных представляет собой график, созданный путем отслеживания взаимосвязей между статьями Википедии, и его можно загрузить здесь.
Я запускаю сообщество Neo4j 1.9.M05 на компьютере с Windows 8, начиная с Neo4j.bat. Я не думаю, что аппаратное обеспечение может быть проблемой, поскольку запрос вызывает только короткий 10-процентный всплеск ЦП. Доступны ГБ свободной оперативной памяти.
Я был бы очень благодарен за подсказки о том, как ускорить выполнение этого запроса.
Изменить: попробовал тот же запрос в немного улучшенной версии того же графа с 283 тыс. узлов и 538 тыс. отношений. Теперь это занимает 20 секунд!
Изменить 2, увеличить лимиты памяти: По совету Майкла я увеличил параметры wrapper.java.initmemory и wrapper.java.maxmemory до 8192 (8 ГБ). Это действительно увеличило объем памяти до 2,25 ГБ java-процесса, работающего под управлением Neo4j, а также увеличило производительность запроса: теперь это около 1 с на прогретых запросах (после третьего запуска). Я также увеличил параметры памяти в конфигурационном файле neo4j.properties до 2 ГБ каждый, но это не дало заметного эффекта. Чтобы все это работало, мне нужна была среда выполнения Java 64b (по умолчанию вы можете легко загрузить для своего браузера 32-битную версию), поэтому я скачал установщик вручную для него. После его установки Neo4j автоматически запустится с ним вместо версии 32b.