Поэтому я попытался загрузить некоторые данные почтового индекса и адреса в neo4j. Я поставил уникальное ограничение, по сути, есть три метки. ПОЧТОВЫЙ ИНДЕКС, АДРЕС И РЕГИОН. REGION и POSTCODE имеют уникальные ограничения на их единственное свойство. Запрос, который мы используем для вставки, будет ОБЪЕДИНЯТЬ РЕГИОН, ОБЪЕДИНЯТЬ ПОЧТОВЫЙ КОДЕКС, СОЗДАВАТЬ АДРЕС, а затем СОЗДАВАТЬ ОТНОШЕНИЯ. Идея состоит в том, чтобы иметь возможность видеть, какие почтовые индексы находятся в каком регионе и сколько адресов имеют один и тот же почтовый индекс, поэтому поведение MERGE важно.
Однако мы обнаружили, что это очень медленно, когда база данных достигает даже довольно среднего размера. Теперь мы ожидали этого, но мы ожидали, что проверки ограничений должны масштабироваться как log(n). Вместо этого производительность линейно зависит от размера базы данных, что очень неожиданно.
Что я могу сделать, чтобы улучшить это, не отказываясь от поведения MERGE? Является ли это следствием ограничения UNIQUE? Теоретически не должно быть никакой разницы между наличием уникального ограничения и просто наличием индекса при использовании слияния, поскольку существует только одно свойство. В любом случае слияние должно знать, существует ли свойство, чтобы решить, следует ли слиться.
Я знаю, что я могу делать разные вещи, чтобы ускорить вставку, использовать загрузчик csv и т. д. Меня интересует здесь улучшение асимптотической производительности. Я думал, что уникальные ограничения должны иметь временную стоимость O (log (n)), а не O (n), и это потенциально имеет огромное значение.
РЕДАКТИРОВАТЬ: Дальнейшее исследование показало, что проблема заключается не в поиске индекса, а вставке R-дерева в пространственный слой. Конкретный код, используемый для вставки, использовал встроенный API, а не шифр, и фрагмент:
graphDB.index().forNodes(s).add(node, "dummy", "variable");
становится все медленнее на O (n) по мере увеличения размера дерева. Очевидно, это ожидаемое поведение для R-деревьев. Это занимает около 0,0005 * количество узлов в слое. С удаленной пространственной вставкой он работает на несколько порядков быстрее и не показывает поведение масштабирования. Предполагаю, что снижение как раз из-за прогрева кеша после запуска.
Кстати, я использую следующий код для запуска пространственного индекса:
Map<String, String> config = SpatialIndexProvider.SIMPLE_POINT_CONFIG;
Transaction tx = graphDB.beginTx();
IndexManager indexMan = graphDB.index();
try{
indexMan.forNodes(lab.name(), config);
tx.success();
} finally {
tx.close();
}
Как это дает вам точку входа в Cypher, но есть ли качественные различия между индексами и слоями? Будет ли слой иметь лучшую производительность, чем индекс, или они оба поддерживаются одинаковыми R-деревьями.
Предложение по этому вопросу: Огромное снижение производительности Neo4J после записи Добавлено в пространственный слой, кажется, что я должен поместить все узлы в базу данных, прежде чем запускать пространственный слой, так как он будет индексироваться намного быстрее, чем инкрементная вставка.
Я попробую это завтра.
LOAD CSV
? - person Brian Underwood   schedule 12.12.2014