16 Марта 02:13
Я некоторое время обдумывал какие данные использовать для замеров и решил, что это будет словарь лексем Зализняка, который я применял в своем проекте поиска опечаток. Это также дало возможность проверить производительность операции выборки по диапазону, которая является весьма критичной для меня. Для взаимодействия с обеими базами использовался Perl, для MongoDB одноименный модуль, а для MySQL модуль DBI. Словарь содержит более 90 000 слов. Структура таблицы/коллекции была проста: кроме первичного индекса я записывал туда само слово и его длину. Процесс заполнения базы данными и стал первым испытанием.

добавление записей/документов в базы
Как видно из графика, время выполнения вставки увеличивается линейно, без каких-либо скачков, а MongoDB опережает MySQL на 40%! Это преимущество по производительности можно легко объяснить отсутствием настоящего ACID, то есть при записи не проверяется и не возвращается её результат. Ради спортивного интереса я включил безопасное добавление записей в MongoDB, это самая верхняя линия, в итоге Mongo стала в 2.5 раза медленнее MySQL. Хочется также отметить, что я специально не использовал никакие методы массовой вставки, хотя обе системы умеют это делать.
Вторым этапом тестирования была выборка, сначала я использовал тот же алгоритм, что и в поиске опечаток, делал выборку в разных диапазонах длин слов. Очевидно, что слов средней длины в словаре больше, и на графиках заметно, как сильно там проседает MongoDB. А по краям, там где количество слов небольшое, почти сравнивается с MySQL. Мой результат совсем не вязался со всеми хвалебными обзорами Mongo, где он в десяток раз опережал MySQL. Первой моей мыслью было добавление индексов на атрибут длины слова, это принесло определенный выигрыш, но только на небольших выборках:

полная выборка данных по диапазонам длин слов с дополнительными индексами и без
(чем меньше тем лучше)
Второй догадкой стала мысль о том, что проблема не в обработке запроса, а в получении результата. Я изменил код так, чтобы он только обрабатывал запрос и получал первый результат. Это оказалось верным решением, и MongoDB на голову опередил MySQL:

обработка запроса и выборка только первого результата по диапазону длины слова
(чем меньше тем лучше)
Очевидно, что драйвер MongoDB, работающий через сокет, лучше, чем REST интерфейс по HTTP, но тем не менее сильно проигрывает TCP соединению при получении результатов. А возможно дело и в самой СУБД. Стоит так же обратить внимание на стабильные результаты Mongo вне зависимости от количества обработанных документов. Внимательный читатель уже понял, что я рассматривал самый худший вариант — холодный запуск на только что созданной БД. Поэтому я решил повторить тесты несколько раз. Для MongoDB ничего не изменилось, а вот MySQL, засчет использования кэша получил рост производительности почти в 7 раз:

горячий запуск выборки первого результата по диапазонам длины слов
(чем меньше тем лучше)
Следующим этапом сравнения производительности было обновление. Вот сравнительные результаты обновления каждой 10ой/100ой/1000ой строки:

обновление каждой 10ой/100ой/1000ой записи
(чем меньше тем лучше)
Тут следует рассказать о том, как работает обновление в MongoDB и какие хитрости используются для достижения такого эффекта. Если обновляемый объект не вырастает в размере, то он просто обновляется в том же месте, где находится, и базе не приходится выделять место и создавать новую копию объекта, что повышает производительность некотрых операций вроде увеличения счетчика. Второй хитростью является так называемая ленивая запись, когда данные из памяти переписываются на диск не сразу после запроса, а через несколько секунд, и если за это время приходит несколько обновлений, то записывается только последнее. Выигрыш от такого поведения очевиден, но существует и обратная сторона — это надежность. Если вдруг БД умрет до момента записи, то потеряются все обновления за этот период.
Заключительным этапом тестирования стало удаление записей. Ниже приведены результаты удаления каждой 10ой/100ой/1000ой строки. И опять MongoDB оказался вне конкуренции.

удаление каждой 10ой/100ой/1000ой записи
(чем меньше тем лучше)
В результате MongoDB — это высокопроизводительная система, которая отлично подходит для проектов с высокой динамикой обновления базы. И в идеале может заменить собой целый стэк технологий ORM/mysql/memcached. Но тем не менее является нишевым продуктом и не подходит для случаев в которых надежность данных является главным приоритетом. Что и требовалось доказать.
1010 просмотров
нет комментариев