Статьи

Neo4j в 377 раз быстрее, чем MySQL?

Примечание куратора. Содержание этой статьи было изначально написано еще в 2011 году. Являются ли эти утверждения по-прежнему действительными? Пожалуйста, дайте нам свои мысли, комментируя ниже.

За последние недели я проделал еще несколько работ над neo4j . И я готов представить еще несколько результатов по скорости ( в моем случае использование neo4j превзошло MySQL в 377 раз! Это более чем на две величины ). Как известно, одна часть моей кандидатской диссертации заключается в создании приложения для социальных сетей вокруг моего сайта социальной сети metalcon.de. Совершенно очевидно, что структура графиков для социальных новостных потоков очень естественна: вы переходите к пользователю. Переходит ко всем своим друзьям или интересующим объектам, а затем проходит на один шаг глубже к вновь созданным элементам контента. Проблема с этим типом приложения заключается в сортировке по времени или релевантности элементов контента. Но прежде чем обсуждать эти проблемы, я просто хочу представить еще одно сравнение между MySQL и neo4j.

Установка:

Я взял довольно маленький набор данных со следующими свойствами:

  • 14986 элементов контента (записей в форуме группы)
  • 1391 группы
  • 854 пользователей, имеющих по крайней мере одну из этих групп в своем списке любимых групп
  • двудольный график отношений фанатов между пользователями и группами

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

Полученные результаты:

В MySQL это будет выглядеть примерно так:

for all (User_ID in Users){

SELECT ce.Text
FROM Entry e
JOIN Topic t ON t.ID = e.Topic_ID
JOIN UserBand ub ON ct.Band_ID = ub.Band_ID
WHERE ub.User_ID = User_ID

}

Несмотря на то, что у нас есть все соответствующие столбцы, эти объединения дорогие. Тем более, что входной стол намного больше, чем 14986 предметов.

Использование MySQL Потребовалось 152 секунды = 2:32 минуты, чтобы создать интересные новостные потоки для всех 854 пользователей или 177 мс на пользователя.

Давайте посмотрим на neo4j:

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

or all (user in index){

for (Relationship rel: user.getRelationships(DynamicRelationshipType.withName(“FAN”), Direction.BOTH)){

Node n1 = rel.getOtherNode(user);
for (Relationship r2: n1.getRelationships(DynamicRelationshipType.withName(“CONTENTITEM”), Direction.BOTH)){
Node n2 = r2.getOtherNode(n1)
edgecnt++;
}
}
}

Несмотря на то, что у нас всего 854 пользователя и 1391 группа, мы получаем 1368270 отношений, которые мы прошли, чтобы получить все элементы контента для всех любимых групп каждого пользователя.

При использовании neo4j это заняло 3,4 секунды или 4 мс на пользователя

Это примерно в 44 раза быстрее, чем MySQL

После прогрева тайников.

При повторении этого эксперимента MySQL не становится быстрее. Я знаю, что у них есть кэш запросов, но я думаю, что он очищается до того, как снова будут выполнены первые запросы. В neo4j этот результат становится еще лучше. Каждый раз, когда я повторял этот эксперимент, время выполнения уменьшалось до тех пор, пока я не достиг уровня 0,4 секунды для задания, которое теперь в 377 раз быстрее, чем MySQL . Лучшая часть этого — масштабирование. Когда мой Социальный график растет, поиск в neo4j остается локальным поиском. больше пользователей и больше обсуждений не означает, что больше переходов от пользователя к его любимым группам. в MySQl, хотя стоимость этих тяжелых объединений просто взорвется.

Да, я знаю, что в MySQL я бы денормализовал свои таблицы, чтобы создать такое приложение, чтобы набрать скорость. Но денормализация означает большую избыточность, и опять-таки граф — это гораздо более естественная структура для социального приложения.

Открытые вопросы! Не стесняйтесь обсуждать их (-:

Хотя есть очень важный открытый вопрос, и это сортировка. Социальные новости, конечно, должны быть отсортированы по времени. в MySQL легко создать индекс по столбцу с метками времени на Contentitems. В этом случае сортировка результатов по времени не увеличит время выполнения.

В базе данных графа с этой конкретной схемой моего графа я не совсем уверен, как получить результаты отсортированным способом. (У кого-нибудь есть какие-нибудь идеи?) Необходимо провести дополнительное тестирование, чтобы выяснить, делает ли сортировка после извлечения все еще мое решение быстрее, чем MySQL или (мое предпочтительное решение), если есть какой-то способ конструировать график таким образом, чтобы для любого пользователя с любым У множества любимых групп есть быстрый способ обхода контента и получения их упорядоченным способом. Я даже предполагаю, что это уже возможно в neo4j, используя траверсеры с первым поиском и сообщая им в порядке обхода отношений. Просто взгляните глубже, и я буду держать вас в курсе.

Я счастлив и открыт для комментариев и предложений! Да, и кто-нибудь может предложить хороший плагин выделения синтаксиса для WordPress?