MongoDB vs MySQL (vs Cassandra): А теперь чуть более правильный ответ

    Собственно, сегодня был запощен топик "Сравниваем производительность MongoDB и MySQL на простом примере", в котором указывалось, что MongoDB превышает по производительности MySQL в разы. Хех, когда такое пишут — я сразу лезу проверять и сомневаться. Я полез в исходники оригинального теста (спасибо за публикацию). И как оказалось автор оригинального топика сделал ошибку в три символа и на самом деле не все так:
    1. В оригинале: MongoDB быстрее MySQL пишет в 1.5 раза (ДА, правда у меня в 3 раза)
    2. В оригинале: MongoDB быстрее MySQL читает в 10 раз (НЕТ, на самом деле — MongoDB примерно на равных плюс-минус 10-30%)
    3. InnoDB vs MyISAM — плюс-минус (в оригинале не тестировалось)
    Сравнение здесь происходит только как key-value storage (запись-чтение по primary key).


    На графике — число операций в секунду, (больше — лучше), шкала логарифмическая.
    Последняя строка — то, что тестировал автор оригинального топика (неправильное, не в критику — все мы ошибаемся и учимся).


    А теперь подробнее об ошибке...

    Итак, ошибка оригинала была в том, что он делал SELECT так:

    test.find({'_id':random.randrange(1, 999999)})

    что возвращало Cursor(!), но не сам объект. То есть обращение к базе не происходит (или по крайней мере чтения данных не происходит). А вот что надо было:

    test.find({'_id':random.randrange(1, 999999)})[0]

    Если бы автор проверял бы, что сохраненное значение (INSERT) равняется вытащенному (SELECT) — такой ошибки не было бы.

    В своем тесте я добавил assert, проверяющий что то, что сохранили — то же, что и читаем. И добавил сравнение с InnoDB (в комментах многие спорили, что может быть намного лучше). Настройки InnoDB дефолтовые.

    Сам тест: по сути оба в качестве «key-value storage» (сохраняем по primary key + value, выбираем по primary key, читаем value). Да, сферический, да, в вакууме.

    Да, внутри теста там есть вызовы assert и str. Разумеется они отжирают часть производительности, но для обоих тестов — их одинаковое число. А нам же просто СРАВНИТЬ производительность надо.

    Больше результатов: Core2duo / WinXP SP3.



    Больше 10000 записей тестировал — соотношение сохраняется. И вроде ни Mongo, ни MyISAM не сдуваются по скорости.

    Исходник:
    yoihj.ru/habr/mongo_vs_mysql.py

    Я не говорю, что 100% прав (может и я в чем ошибся), так что проверяйте меня тоже.

    P.S. Да, у меня выборка была последовательная, если же переключить ее на случайную (доставать каждый раз элемент со случайным номером) — ситуация меняется, но не кардинально, расположение сил все то же. Убедиться можно заменив в SELECTах i1 = str(i+1) на i1 = str(random.randint(1,cnt-1)+1).

    В комментах fallen протестировал этим же кодом все под Linux + InnoDB_Plugin. Соотношение сил — примерно то же, но ровнее:

    Linux + InnoDB_Plugin


    «Core i7 920, 2GB RAM, Fedora 12 x64, mysql 5.1.44 + InnoDB 1.0.6 скомпилированные icc, mongodb 1.2.4 x64, sata диск обычный.»

    Выводы:


    1. На запись MongoDB быстрее, если использовать как key-value storage;
    2. Чтение примерно одинаково происходит;
    3. Обе системы — вполне приличные, никто не устарел, никто никого не убил, явного проигрывающего нет.


    vs Cassandra


    И интереса ради добавлена Cassandra + pycassa (под win32) — сразу скажу — с ней у меня никакого опыта и много непонятного (.remove() не удаляет записи, а только очищает их, сами они остаются… + eventual consistency — оооооооочень трудно тестировать!) — полное прыгание с бубном в темноте, так что считайте просто развлекательным тестом.



    import pycassa
    client = pycassa.connect()
    cf = pycassa.ColumnFamily(client, 'Keyspace1', 'Standard1')
    
    # CASSANDRA INSERT
    start_time = time.clock()
    for i in xrange(cnt):
    	i1 = str(i+1)
    	cf.insert(i1, {'value': i1})
    report('Cassandra INSERTs')
    
    list(cf.get_range())
    
    # CASSANDRA SELECT
    start_time = time.clock()
    for i in xrange(cnt):
    	i1 = str(i+1)
    	obj = cf.get(i1)['value']
    	assert(obj == i1)
    report('Cassandra SELECTs')



    Йои Хаджи,
    вид с Хабра

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 71

      +6
      В том топике просто такая картинка красивая в начале, вот никто и не заподозрил ошибки :)
        0
        Да, за мою графику можете стрелять сразу ) Виновен, не дизайнер.
          +2
          Да, и спасибо за разбор полетов. А то я сам очень удивился таким результатам.
            0
            Хм, странно всё таки в тестах, которые я видел раньше монго был быстрее (но не в 10 раз конечно)…
              0
              Я опять же говорю — проверяйте, я мог тоже ошибится в чем-то — на то и исходник.
                +1
                Ну тесты то сферические. Я видел как результаты где Монго выигрывает, так и где они с мускулем идут на равных.
                  0
                  Да, я тоже погуглил — у кого-то выигрывает, у кого-то проигрывает. Да и во всех базах есть нюансы (multi_insert, INSERT DELAYED, begin-commit и т.п.)
                    0
                    На мой взгляд если нужна реляционная БД, то как бы Вы не изгалялись, Мускул будет эффективнее, а если нужна документо ориентированная БД, вот тогда Монго покажет свою мощь, и на некоторых вещах можно добиться и заявленного в перидущей статье 10 кратного преимущества.
                      +1
                      Дело еще в том, что Mongo изначально позицианируется как база, куда значительно чаще будет записывать данные, чем читать.
                        0
                        Вот с этим плюсом я согласен — есть очень много проектов, которые нагружены именно на запись! И Монго тут показывает преимущество, даже в сферическом тесте.
            0
            Добавили бы ещё XtraDB иль хотяб INNODB plugin
            Ну а больше всего хочется увидеть XtraDB с патчами, не внесёнными в основу :)
              +1
              А оно есть для Win32? Если есть — добавить в тест не проблема.
                0
                Винда мля))))
                  0
                  Угу. Ща ради интереса запущу виртуализированную Fedora сравним заодно с виндой :)
                    0
                    (разумеется сравним — не поменяется ли расположение сил, а не сравним цифры)
                      +2
                      10000 items
                      MyISAM INSERTs 27.0K per sec
                      INNODB INSERTs 28.6K per sec
                      Mongo INSERTs 62.5K per sec
                      MyISAM SELECTs 20.8K per sec
                      InnoDB SELECTs 20.8K per sec
                      Mongo SELECTs 12.0K per sec
                      Mongo cursor(WRONG!) SELECTs 166.7K per sec

                      100000 items
                      MyISAM INSERTs 27.9K per sec
                      INNODB INSERTs 28.4K per sec
                      Mongo INSERTs 73.0K per sec
                      MyISAM SELECTs 21.4K per sec
                      InnoDB SELECTs 21.1K per sec
                      Mongo SELECTs 14.8K per sec
                      Mongo cursor(WRONG!) SELECTs 169.5K per sec

                      100000 items
                      MyISAM INSERTs 27.9K per sec
                      INNODB INSERTs 27.9K per sec
                      Mongo INSERTs 78.7K per sec
                      MyISAM SELECTs 21.4K per sec
                      InnoDB SELECTs 21.1K per sec
                      Mongo SELECTs 14.4K per sec
                      Mongo cursor(WRONG!) SELECTs 169.5K per sec

                      Core i7 Fedora 12, ноликов пришлось добавить, при меньшем кол-ве выполняется за 0 секунд и вылезает деление на 0
                      НЕ скрываю, разочарован Innodb plugin ом :(
                        0
                        Насчет деления на ноль — это баг Питона.
                        Там на Linux надо time.clock() было надо поменять на time.time().
                        У Винды time.clock() — это точные (неокругленные) данные, а у Linux — time.time() — точный.
                        Парадокс, но факт :)

                        Спасибо, кстати за результаты. Радует, что отношения примерно те же вышли.
                          0
                          Хотя вообще-то странно: InnoDB нос к носу с MyISAM — уверены что таблица создалась с типом InnoDB_Plugin? Обычно такая ровность — это повод подумать что что-то не так.
                            0
                            Вы чертовски правы, у меня дефолт — иннодб
                              0
                              на сколько мне известно, дефолт innodb должен читать медленней чем дефолт myisam
                                0
                                Не, там про другое — там первая таблица создается с дефолтом, а вторая — иннодб. Получилось что обе создались как иннодб.
                                  0
                                  тогда почему такая разница очевидная в тестах?:)
                                    0
                                    Где? Речь про это:
                                    habrahabr.ru/blogs/mysql/87620/#comment_2625002

                                    10000 items
                                    MyISAM INSERTs 27.0K per sec
                                    INNODB INSERTs 28.6K per sec

                                    100000 items
                                    MyISAM INSERTs 27.9K per sec
                                    INNODB INSERTs 27.9K per sec

                                    на самом деле тут где написано «myisam» был тоже «innodb» (по умолчанию созданный так)…
                                      0
                                      я про изначальные числа из топика
                                        0
                                        млин… я не знаю как подробнее объяснить уже.
                                        fallen тестировал на линухе с innodb_plugin (отдельно от топика! в этой ветке!), у него получились результаты с ошибкой (обе таблицы innodb, про которое он и сказал, что одна таблица создалась по дефолту (Как иннодб), а вторая с четким указанием, (тоже иннодб!)), ошибку он исправил. у него настройки по умолчанию (дефолту) создавать innodb, у меня по дефолту — myisam…

                                        при чем здесь изначальные числа из топика?
                +1
                :) и почему в подобных тестах не указывают настройки БД? у mysql они более чем скромные по умолчанию :)
                  0
                  Всегда с удивлением читаю тесты производительности на неизвестных конфигурациях, на неизвестных версиях субд… Замеры производительности вообще довольно обширная и сложная тема, вплоть до копирования раздела диска где БД лежит, чтобы при последующем ПОВТОРНОМ проведении теста результаты были на тех же условиях. Довольно не плохо об этом еще написано в «High performance Mysql». А так… Это все рокет сайнс…
                    +2
                    Логично предположить, что человек запускает всё на последних версиях. Хорошо, что хоть такие тесты есть, он рисуют общую картину.
                  • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      У меня подозрение, что это вторая попытка за день сравнить хрен с пальцем.
                        +2
                        Чтобы серьезно сравнивать производительность баз данных, нужно заниматься этим лет тридцать, и то останутся вопросы
                        — какой режим БД (универсальный, быстрая запись (OLTP), быстрые запросы (Warehousing))
                        — какая файловая система (или вообще row partition)
                        — какое железо (диск — процессоры — память хотя бы)
                        — сколько параллельных запросов работало
                        — писались ли логи UNDO и REDO в каждом случае.

                        Для школьников исследования, подобные вашим, еще адекватны, а для более старших товарищей — уже не очень.
                          0
                          Зря вы на человека наезжаете, он сделал разбор статьи с тестом. Да может у него для майскуля не оптимальные настройки, но если их изменить, то это лишь подчеркнет картину, что тот тест был необъективен.
                            +2
                            Мне это все вообще напоминает какую-то игру. А давайте посмотрим, сколько записей и чтений наша СУБД сделает в один поток за секунду? Давайте! Отчего б не посмотреть. Ооо. А ваша-то в 3 раза медленнее, что ж вы так.

                            Это как сравнивать автомобили по их количеству оборотов двигателя в минуту на нейтралке. Ничего не скажет, как быстро, а главное как хорошо поедет та или иная машина.
                              –3
                              Не нравится — не читайте.
                              Сделайте сами профессиональный обзор с перечислением всех настроек и всего оборудования и показывайте.

                              «тысячи каментов по всей сети, и что мы видим – кругом говно, говно, говно» © mr. Freeman
                                +1
                                > Не нравится — не читайте.

                                Это неправильно. Я ЧИТАЮ. Я ДУМАЮ, что сравнивать базы данных на основании ограниченного количества запросов — методически неверно. Я ПИШУ об этом.

                                А то так начнут писать что дважды два пять — и что, тоже не читать?
                                Большинство "преступлений" совершается под молчание равнодушных.
                                  –2
                                  Вот я, к примеру, не знал что такое mongodb. Хотел попробовать в одном проекте, но теперь вижу, что ценность оного для меня никакая, так как там упор на чтение.
                                  Вы — герой. Вам не всё равно. Раз такой умный — тусите с каспаровым, ему тоже не всё равно. И не лезьте в садик к школоте, как вы выразились!
                                    0
                                    > Хотел попробовать в одном проекте, но теперь вижу, что ценность оного для меня никакая, так как там упор на чтение.

                                    Вот, блин, все верно — вот аудитория такого теста (и я тоже) — и он нам полезен! (И мне самому тоже — сравнить не очень известную систему и понять — не устарел ли уже mysql).
                                    0
                                    Да, соглашаюсь, но Вы же не можете утверждать, что тест НЕ верный? Он просто не отвечает Вашим требованиям об опубликованной информации. Но если бы я все это описал — от этого мускуль бы не стал в три раза быстрее?

                                    Опять же — мне лично (как автору этого топика) важно например было узнать, что в среднем монго опережает mysql на запись и значительно. Разница в 10-40% на чтение — для меня не играет роли и не для кого особо не должна (в таких тестах), потому что такие выигрыши можно как раз делать разным использованием технологий (bulk insert, begin-commit, multi_get, отложенные ключи и т.п.).

                                    Просто для чего такой тест может быть полезен — так это, например, увидели бы мы что мускуль проигрывает на таких задачах в 10 раз… то можно было бы сделать вывод, что мускуль — пережиток прошлого. Такого вывода сделать нельзя, можно только, что системы примерно равны по производительности и дальнейшее выжимание мощности из них зависит от самого программера.

                                    Сколько ни тужься программеру — но Python не обгонит C — мы это знаем благодаря таким же «сферическим» тестам и можем делать разумный выбор.
                                      0
                                      Что означают результаты проведенного вами теста? Как можно их интерпретировать?

                                      Допустим, вы делаете вывод «Монго выигрывает для приложений, у которых узкое место — запись, а не чтение». При этом надо понимать, что вы имеете ввиду узкую нишу приложений, которые делают миллион мелких запросов в один поток на машине с медленным винтом, один за другим.

                                      Помимо операций чтения/записи есть издержки на работу ЦП. Они несущественны на машинах с медленными винтами, но для серверов с RAID-массивами могут быть более ощутимы. Есть также очень сильные издержки на конкуренцию (concurrency), то есть одновременный доступ к объектам БД множества пользователей, когда часть пытаются писать, а остальные — читать. Согласитесь, распространенная ситуация.

                                      «Сколько ни тужься программеру — но Python не обгонит C — мы это знаем благодаря таким же «сферическим» тестам и можем делать разумный выбор.»
                                      Предположим, у нас есть 1) приложение, которое большую часть времени проводит в ожидании сети, диска или команды пользователя; 2) программа, которая ищет первые 100 тысяч простых чисел. Во втором случае питону действительно не догнать си. В первом — спорный вопрос, издержки ЯП скорее всего будут меньше погрешности для издержек на ожидание пользователя.
                                        –1
                                        Каждый интерпретирует, как захочет. Это информация к размышлению, а не исчерпывающий анализ. Информация для «ПОДУМАТЬ».
                                          +1
                                          Вообще логично предположить, что если продукт называют СУБД, и он уже некоторое время присутствует на рынке, то он должен по крайней мере неплохо справляться с самыми базовыми операциями, которые от него требуются.

                                          В таком случае это тестирование демонстрирует, что ДА, действительно, разработчики обеих СУБД не облажались.

                                          Но мы же не сравниваем операционные системы по скорости, с которой они могут забить оперативку машины процессами Hello World.exe (.app/etc)?
                                        +1
                                        Дело в том, что если у вас упор при линейной записи в любой БД получается не в жестком диске, вы явно где-то неправы. А он должен быть одинаков для любых БД (т.к. ограничении в блочном устройстве). Кроме того, по умолчанию принцип sync-а для mysql mysam, innodb и mongodb разный, надо все это приводить к одному знаменателю, как только вы это сделаете производительность в несколько раз на запись упадет для обоих тестов.

                                        В многочисленных вставках ограничения возникают как правило не в скорости записи на диск, а в расчете индексов (b-tree как правило. Кстати у каждого своя реализация, вот ее интересно было бы сравнить). Тут тоже про это ничего не сказано.

                                        Кроме того, у вас скорость чтения практически равняется скорости записи. Я себе такой представить могу только если вы совсем не используете память (и память БД, и память кеша ФС ОС). Как такое может быть я себе даже не представляю.

                                        Вот пример интересного сравнения
                                        www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/
                                          +1
                                          т.е. я поддерживаю — тест не адекватен.
                                            –1
                                            Поддерживаю — тестируйте сами и пишите полный всесторонний обзор.
                                              +1
                                              У меня слишком частные задачи для такого общего обзора :)

                                              Вы не обижайтесь, я просто советую на что обратить внимание. Вас же должно было насторожить что SELECT-ы медленнее INSERT-ов. Я вообще такого не видел.

                                              Думаю у вас сильную погрешность ввело еще то, что клиент (питон-скрипт) и сервер-ы работали на одном железе — т.е. делили ресурсы, а это тоже должно «зашумлять» объективность результата.
                                  0
                                  Мало смысла на самом деле гонять всё это дело на своих локальных ноутбуках. Надо, кстати, учесть, что и скорости дисков, как бы, тоже решают в данном вопросе, а не только CPU и оперативка, особенно, с учётом любви MongoDB к преаллокации.
                                  Хотите реальности — поднимаем на реальных серверах в конкретных системах, с конкретными конфигурациями и даём реальные стресс-тесты. И тогда получаем сколь-нибудь реальные результаты. А так — это воздух.
                                    +2
                                    Хм, действительно, видимо вы правы. Чтение данных в моём случае не происходило, признаю свою ошибку.
                                    Спасибо за критику)
                                      +1
                                      Нет проблем, технология новая — я сам, в общем-то, полез проверять — а есть ли выборка вообще :)
                                      0
                                      а вот я вчера тестировал stas-agarkov.livejournal.com/17659.html
                                      немного не понял про скорость селектов. у меня хоть 140 тыщ выборка, хоть 30. время одинаковое практически.
                                      я делал count, то есть не просто получал курсор. а потом я еще и сумму считал. вторая сумма меньше времени считалась, потому что там цикл по 30 тысячам, а первый раз — по 140 тысячам.

                                      можете прояснить?
                                        0
                                        А может быть Mongo медленный из-за того, что например его библиотека-клиент медленно десериализует данные, или еще что-то там, а майскульная — на Си и работает быстро?
                                          0
                                          библиотека клиент тоже на си
                                          0
                                          Интересно бы еще многопоточно погонять это дело…
                                            0
                                            монго занимает все ядра…
                                              0
                                              этот же тест, без изменений вообще:
                                              MyISAM INSERTs 2.9K per sec
                                              INNODB INSERTs 3.5K per sec
                                              Mongo INSERTs 17.6K per sec

                                              MyISAM SELECTs 2.6K per sec
                                              InnoDB SELECTs 2.8K per sec
                                              Mongo SELECTs 3.3K per sec

                                              В общем, вывод один — этот тест бесполезен
                                                0
                                                Ну у вас те же результаты, о чем я и говорю — на запись монго быстрее, на чтение — примерно то же самое что и мускуль.
                                                  +1
                                                  У вас на треть быстрее mysql, у меня на ту же треть, но уже монго. Как то совсем оно примерно.
                                                    0
                                                    Ну так в результате мы возьмем среднее между двумя тестами (у меня и у Вас) и получается — что примерно равны — на каких-то настройках (оборудовании) будет монго вырываться вперед, на каких-то мускуль — это уже от конкретики зависит. А базовая линия — что примерно одинаковы.
                                                0
                                                ну а теперь попробуем сделать репликацию/sharding и поднять количество коннектов к базе для чистоты эксперимента
                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                    +1
                                                    проснись, в монге нет таблиц. Попробуй записывать в майсиквель документы произвольного формата, и, кстати, с индексами по произвольной вложенности полям в документе. И map-reduce не забудь. А то тупое чтение запись — это как-то неинтересно. С такими успехами и в CVS файлик писать можно.
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                    0
                                                    Все, кто предлагает расширить тест, уточнить его и т.п. — мне это не интересно, я узнал что хотел — что все примерно одинаковые — никто никого не убил, никто не тупит. А дальше — все исходники у вас есть — дерзайте.
                                                      0
                                                      PyMongo установлен с C-расширением?

                                                      api.mongodb.org/python/1.5%2B/installation.html#installing-without-the-c-extension
                                                        0
                                                        с C-расширением — через easy_install
                                                        +3
                                                        Тест не такой уж и воздух. Он показал, что 99% тех, кто будет ставить одну из баз, получат одинаковую производительность — так как подавляющее большинство настройки не меняет. А оставшийся один процент уже будет думать более продвинуто — и другие базы посмотрит типа postgres, и режимы записи проверит, и разбросает индексы и таблицы по разным дискам. Но зависеть это будет уже от имеющихся ресурсов в каждом конкретном случае.
                                                          +2
                                                          Давно такой интересной и полезной статьи не было, спасибо!

                                                          Поддерживаю предыдущий коммент, жалко, что нету PostgreSQL. Вот это было бы весьма и весьма кстати. Ещё не указано, как был настроен кэш в MySQL, это тоже очень важный момент.

                                                          А в целом ещё раз — спасибо.
                                                            +1
                                                            Потестировал у себя Mongo SELECTы и заметил следующее:
                                                            из питона получаю 6.6K per sec
                                                            на аналогичной key-value базе из джавы в один поток получаю 18K per sec
                                                            из джавы в 10 потоков получаю 30K per sec
                                                            дальнейшее увеличение кол-ва потоков у меня уже выигрыша не дает

                                                            При этом для MySQL и питон и джава выдают практически одинаковый результат: ~9K per sec

                                                            Получается, что драйвер Mongo под питон тормозит и что, в любом случае, лучше тестировать базы в несколько потоков, т.к. это ближе к реальной жизни.
                                                              0
                                                              Давайте сделаем тесты и обсудим на DEVCONF.ru
                                                              тема MongoDb — весьма актуальна…
                                                              devconf.ru/phpconf/offers/26
                                                                –1
                                                                Такая ситуация интересная произошла, намедни наткнулся на статью, прочитал с удовольствием, улыбнулся, подумал про себя: «ведь сейчас везде есть MySQL, не проще ли раздобыть хостинг с мускулом, либо установить его на сервере». По прошествию нескольких дней меня попросили написать 1 штуку, нужно использовать БД, а мускула нет на сервере и установить — гемор очень большой (не будем вдаваться в подробности). Бегом полетел искать эту статью, на этот раз добавил в favorites :)). Автору большое спасибо!!!
                                                                  –1
                                                                  ой-ой, я ошибся темой, сори-сори-сори!
                                                                  0
                                                                  Тестировал аналогичные продукты на linux debian.
                                                                  Получилось, что cassandra очень сильно отстает от остальных по всем операциям.
                                                                  Слышал, что cassandra хорошо себя показывает только на очень мощных серверах.

                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                  Самое читаемое