Я использую NEO4j 3.5 для хранения и запроса отношений между людьми.У меня есть узлы с меткой «Пользователь» и связи с меткой «Друзья».Я могу найти друзей друзей, но запрос занимает слишком много времени.В настоящее время возвращается через 4 с до 6 с.Это не высокопроизводительная транзакционная база данных neo4j, и на сервере достаточно ресурсов ЦП и памяти.Нагрузка на сервер меньше 3, а ядер 8.Это работает на экземпляре AWS EC2.В базе данных приблизительно 250 000 узлов, а общий размер базы данных составляет менее 750 МБ.
Вот запрос, который я сейчас использую:
MATCH (user:User {user_id:1145})-[:FRIENDS*3]->(fof:User)
WHERE NOT (user:User)-[:FRIENDS]->(fof:User)
RETURN count(distinct fof.user_id)
Этот запрос шифра возвращает число 69 704, что правильно.
Какие оптимизации могут быть внесены либо в запрос на шифрование, либо в механизм базы данных NEO4j для более быстрого возврата результатов?
План выполнения
+-----------------------+----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Cache H/M | Identifiers | Ordered by | Other |
+-----------------------+----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +ProduceResults | 0 | 1 | 0 | 0/0 | count(distinct fof.user_id) | | 0.0 |
| | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +EagerAggregation | 0 | 1 | 326421 | 0/0 | count(distinct fof.user_id) | | 0.0 |
| | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +AntiSemiApply | 0 | 256717 | 0 | 0/0 | anon[33], fof, user | user.user_id ASC | 0.0 |
| |\ +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| | +Expand(Into) | 0 | 0 | 8006149 | 0/0 | REL80, fof, user | | 0.0; (user)-[ REL80:FRIENDS]->(fof) |
| | | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| | +Filter | 1 | 260120 | 520240 | 0/0 | fof, user | | 0.0; fof:User |
| | | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| | +Argument | 1 | 260120 | 0 | 0/0 | fof, user | | 0.0 |
| | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +Filter | 0 | 260120 | 260120 | 0/0 | anon[33], fof, user | user.user_id ASC | 0.0; fof:User |
| | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +VarLengthExpand(All) | 0 | 260120 | 267999 | 0/0 | anon[33], fof, user | user.user_id ASC | 0.0; (user)-[anon[33]:FRIENDS*3..3]->(fof) |
| | +----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+
| +NodeIndexSeek | 1 | 1 | 3 | 0/0 | user | user.user_id ASC | 0.0; :User(user_id) |
+-----------------------+----------------+--------+---------+-----------+-----------------------------+------------------+--------------------------------------------+