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