Этот вопрос аналогичен этим двум: 16283441, 15456345.отношения с соседними соседями cypher query
ОБНОВЛЕНИЕ: здесь database dump.
в БД 190K узлов и 727K отношений (и 128 Мб дискового использования базы данных), я хотел бы выполнить следующую команду query:
START start_node=node(<id>)
MATCH (start_node)-[r:COOCCURS_WITH]-(partner),
(partner)-[s:COOCCURS_WITH]-(another_partner)-[:COOCCURS_WITH]-(start_node)
RETURN COUNT(DISTINCT s) as num_partner_partner_links;
В этом DB 90% узлов имеют отношения 0 , а оставшиеся 10% имеют от 1 до 670, поэтому самая большая сеть, к которой может вернуться этот запрос, не может иметь более 220 Кбит/с (670 * 670)/2).
На узлах с партнером_partner_links менее 10 тыс. Запрос занимает 2-4 секунды, когда он прошивается. Для более узких узлов (ссылки 20-45K) требуется около 40-50 секунд (не знаете, сколько потребуется для самых подключенных).
Указание направления отношений помогает немного, но не так много (но тогда запрос не возвращает то, что мне нужно для его возврата).
Профилирование запроса на одном из самых больших узлов говорит:
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATE48d9beec-0006-4dae-937b-9875f0370ea6"], returnItemNames=["num_partner_links"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATE48d9beec-0006-4dae-937b-9875f0370ea6,Distinct)"], _rows=1, _db_hits=0)
==> PatternMatch(g="(partner)-['r']-(start_node)", _rows=97746, _db_hits=34370048)
==> TraversalMatcher(trail="(start_node)-[ UNNAMED3:COOCCURS_WITH WHERE true AND true]-(another_partner)-[s:COOCCURS_WITH WHERE true AND true]-(partner)", _rows=116341, _db_hits=117176)
==> ParameterPipe(_rows=1, _db_hits=0)
neo4j-sh (0)$
Я не вижу, почему бы это так медленно, большая часть материала должна быть в памяти в любом случае. Возможно ли, чтобы это было менее чем за 100 мс, или neo4j не справляется с этим? Я мог бы поставить весь дб где-то, если это поможет ..
Самая большая загадка в том, что тот же запрос работает медленнее, когда переписаны для использования с различными узловыми символов :)
START n=node(36)
MATCH (n)-[r:COOCCURS_WITH]-(m),
(m)-[s:COOCCURS_WITH]-(p)-[:COOCCURS_WITH]-(n)
RETURN COUNT(DISTINCT s) AS num_partner_partner_links;
START start_node=node(36)
MATCH (start_node)-[r:COOCCURS_WITH]-(partner),
(partner)-[s:COOCCURS_WITH]-(another_partner)-[:COOCCURS_WITH]-(start_node)
RETURN COUNT(DISTINCT s) AS num_partner_partner_links;
Бывший всегда бежит в +4,2 секунды, а последний менее 3,8, независимо от того, сколько раз я запускаю один и другой (чередующийся) !?
SW/HW деталь: (расширенный) Neo4j v1.9.RC2, JDK 1.7.0.10, Макбук про с SSD диском, 8GBRAM, 2 Core i7, со следующей конфигурацией: Neo4j
neostore.nodestore.db.mapped_memory=550M
neostore.relationshipstore.db.mapped_memory=540M
neostore.propertystore.db.mapped_memory=690M
neostore.propertystore.db.strings.mapped_memory=430M
neostore.propertystore.db.arrays.mapped_memory=230M
neostore.propertystore.db.index.keys.mapped_memory=150M
neostore.propertystore.db.index.mapped_memory=140M
wrapper.java.initmemory=4092
wrapper.java.maxmemory=4092
Вы правы на оба, ваш запросе шифровать несколько быстрее, и запрос обхода является по крайней мере, в 2 раза быстрее! Но он все еще не там, где мне нужно:/на результатах 10K он занимает 1сек, для самого большого узла - 20 сек. Ps. в вашем обходном запросе было 2 ошибки, надеюсь, что мне хорошо отредактировать ваш ответ. – milan
Вы можете получить немного скорости, добавив идентификаторы отношений в набор. Я снова редактировал код. Вы снова выиграете, но, конечно, не будете делать чудес. – tstorms
Самые большие узкие места в том, что вам нужно пройти в обоих направлениях. Невозможно ли смоделировать ваши данные только в одном направлении? – tstorms