Плохая производительность вставки пространственного слоя

Поэтому я попытался загрузить некоторые данные почтового индекса и адреса в 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 после записи Добавлено в пространственный слой, кажется, что я должен поместить все узлы в базу данных, прежде чем запускать пространственный слой, так как он будет индексироваться намного быстрее, чем инкрементная вставка.

Я попробую это завтра.


person phil_20686    schedule 12.12.2014    source источник
comment
Уникальное ограничение также добавляет индекс, так что у вас все должно получиться. Это то, что вы делаете с LOAD CSV?   -  person Brian Underwood    schedule 12.12.2014
comment
Было бы полезно увидеть код/запросы, если вы можете поделиться ими.   -  person Brian Underwood    schedule 12.12.2014
comment
Нам нужно увидеть некоторые запросы. MERGE, естественно, попытается выполнить поиск перед созданием, поэтому наличие таких вещей, как метки и индексы, которые ускорили бы этот поиск, кажется актуальным. Также есть проблемы с кешированием — вам следует рассмотреть возможность публикации вашей конфигурации и того, как выглядят ваши настройки кеша. neo4j.com/docs/stable/configuration-caches.html Наконец, можно вы даете нам представление о том, какие новые вещи вы ОБЪЕДИНЯЕТЕ? Всегда ли это создает новые вещи или только иногда? (местность ссылки тоже имеет значение)   -  person FrobberOfBits    schedule 12.12.2014
comment
По оси Y измеряется время загрузки 200 графиков. Что на 1 графике? Это только 1-6 почтовые индексы? Как они связаны? Вы ОБЪЕДИНЯЕТЕ только почтовые индексы, отношения между уже существующими почтовыми индексами или что?   -  person FrobberOfBits    schedule 13.12.2014


Ответы (1)


Какую версию Neo4j вы используете?

Да, поделитесь своими вопросами.

Если вы используете LOAD CSV, у вас будет более высокая производительность при создании узлов по отдельности сначала с MERGE, а затем во втором проходе создайте отношения с MATCH ... MATCH ... CREATE ...

см. также: http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/

Если вы не используете LOAD CSV, выполняете ли вы отдельные небольшие транзакции? Если это так, имеет смысл объединить их, например, в 1000 операций на транзакцию.

Можете ли вы также проверить, что ваши ограничения действуют с помощью «:schema» в браузере или «schema» в оболочке?

И проверьте, что индекс/ограничение действительно используется, профилируя ваш запрос в оболочке? Просто добавьте к нему префикс profile.

person Michael Hunger    schedule 13.12.2014