Счетчик Neo4j значительно увеличивает время выполнения и не хватает памяти - PullRequest
0 голосов
/ 02 мая 2019

Я использую Neo4j для хранения данных о рейтингах фильмов. Я хотел бы посчитать количество фильмов, которые оценили оба пользователя. При выполнении запроса

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,b,c limit 1000

завершается менее чем за секунду, однако работает

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,count(b),c limit 1000

база данных не может завершить запрос, так как куче не хватает памяти, которую я установил как 4gb. Я правильно использую функцию подсчета? Я не понимаю, как производительность между этими двумя запросами может так сильно различаться.

Ответы [ 2 ]

0 голосов
/ 02 мая 2019

MissingNumber имеет хорошее объяснение того, что происходит.Когда вы выполняете агрегацию, нужно учитывать, что весь набор правильно выполняет агрегацию, и это должно произойти до LIMIT, и это приводит к огромным потерям в вашем пространстве кучи.

Как альтернатива в вашем случае, вы можете попробовать следующее:

match (a:User)-[:RATED]->()<-[:RATED]-(c:User)
with DISTINCT a, c
where id(a) < id(c)
limit 1000
match (a)-[:RATED]->(m:Movie)<-[:RATED]-(c)
with a, c, count(m) as moviesRated
return a, moviesRated, c

Переместив LIMIT вверх перед агрегацией, но используя вместо этого DISTINCT, чтобы убедиться, что мы имеем дело только с парой узлов в этом шаблоне один раз (и применяем предикат на основеидентификаторы графов, чтобы мы никогда не имели дело с зеркальными результатами), мы должны получить более эффективный запрос.Затем для каждой из этих 1000 пар a и c мы снова расширяем схему и получаем фактические значения.

0 голосов
/ 02 мая 2019

Я столкнулся с подобной подобной ситуацией и решил эту проблему, используя следующий подход, это будет применимо к вам.

Я использовал набор данных, имеющий: (TYPE_S) - 380 узлов (TYPE_N) - 800000node [: S_realation_N] - 5600000 отношений

Запрос первый:

match (s:TYPE_S)-[]-(n:TYPE_N) return s, n limit 10

Это заняло 2 миллисекунды.

Как только 10 образцов (отношений) будут найдены вдБ, neo4j просто возвращает результат.

Запрос второй:

match (s:TYPE_S)-[]-(n:TYPE_N) return s, sum(n.value) limit 10

Это заняло ~ 4000 миллисекунд.

Этот запрос может выглядеть так же быстро, как и последний.Но, конечно, он не будет таким же быстрым, как предыдущий, из-за агрегации.

Причина :

Чтобы запрос агрегировал по шаблону, Neo4j должен загрузитьвсе пути, которые соответствуют заданному шаблону (это больше 10 или заданный предел здесь и будут 5600000 согласно моему набору данных) в оперативную память перед выполнением агрегации.Позже эта агрегация выполняется на 10 полных записях узлов S_TYPE, поэтому теперь она попадает в указанный формат возврата с заданным пределом.Остальные отношения у барана затем смываются.Это означает, что на момент запуска загружаются данные лота, которые впоследствии будут игнорироваться из-за ограничения.

Таким образом, чтобы оптимизировать время выполнения и использование памяти, здесь вы должны избегать части запроса, которая приводит кзагрузка данных, которые позже будут игнорироваться.

Вот как я оптимизировал это:

match (s:TYPE_S) where ((s)-[]-(:TYPE_N)) 
with collect(s)[0..10] as s_list
unwind s_list as s
match (s)-[]-(n:TYPE_N) return s, sum(n.value)

Это заняло 64 миллисекунды.

Сейчасneo4j сначала помещает в список 10 узлов типа TYPE_S, которые имеют отношения с TYPE_S, а затем сопоставляет шаблон с этими узлами и получает их данные.Это должно работать и работать лучше, чем query2, так как вы загружаете ограниченный набор записей в оперативную память.

Вы можете использовать этот аналогичный способ для создания запроса, закорачивая 1000 (a, b) различных пар пользователей и затем агрегируя их.Но этот подход потерпит неудачу в случае необходимости упорядочения по совокупности.

Причина, по которой вашему запросу не хватает памяти, заключается в том, что вы используете оперативную память 4 ГБ и выполняете запрос, который может загрузить много комбинационных данных вram (иногда это может превышать размер вашего дБ из-за множественности комбинаций данных, определенных в ваших шаблонах, в вашем случае, даже если у вас 50 уникальных пользователей, у вас есть 50 * 49 возможных уникальных комбинаций шаблонов, которые могут быть загружены в ram),Также могут повлиять другие транзакции и запросы, выполняющиеся параллельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...