MySQL против MongoDB 1000 читает

231

Я очень волновался о MongoDb и тестировал его в последнее время. У меня была таблица с сообщениями в MySQL с примерно 20 миллионами записей, индексированных только в поле под названием "id".

Я хотел сравнить скорость с MongoDB, и я провел тест, который будет получать и печатать 15 записей случайным образом из наших огромных баз данных. Я запросил около 1000 раз каждый для mysql и MongoDB, и я удивлен, что не вижу большой разницы в скорости. Возможно, MongoDB в 1,1 раза быстрее. Это очень разочаровывает. Есть ли что-то, что я делаю неправильно? Я знаю, что мои тесты не идеальны, но MySQL наравне с MongoDb, когда дело доходит до чтения интенсивных обязанностей.


Примечание:

  • У меня есть двухъядерный + (2 потока) i7 cpu и 4GB ram
  • У меня есть 20 разделов на MySQL каждый из 1 миллиона записей

Пример кода, используемый для тестирования MongoDB

<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$time_taken = 0;
$tries = 100;
// connect
$time_start = microtime_float();

for($i=1;$i<=$tries;$i++)
{
    $m = new Mongo();
    $db = $m->swalif;
    $cursor = $db->posts->find(array('id' => array('$in' => get_15_random_numbers())));
    foreach ($cursor as $obj)
    {
        //echo $obj["thread_title"] . "<br><Br>";
    }
}

$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000) ;

    }
    return $numbers;
}

?>


Пример кода для тестирования MySQL

<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$BASE_PATH = "../src/";
include_once($BASE_PATH  . "classes/forumdb.php");

$time_taken = 0;
$tries = 100;
$time_start = microtime_float();
for($i=1;$i<=$tries;$i++)
{
    $db = new AQLDatabase();
    $sql = "select * from posts_really_big where id in (".implode(',',get_15_random_numbers()).")";
    $result = $db->executeSQL($sql);
    while ($row = mysql_fetch_array($result) )
    {
        //echo $row["thread_title"] . "<br><Br>";
    }
}
$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000);

    }
    return $numbers;
}
?>
  • 0
    какой у вас MySQL Query?
  • 9
    Каковы фактические времена?
Показать ещё 13 комментариев
Теги:
performance

7 ответов

532
Лучший ответ

MongoDB не магически быстрее. Если вы сохраняете одни и те же данные, организованные в основном тем же способом, и получите доступ к нему точно так же, то вам действительно не следует ожидать, что ваши результаты будут совершенно разными. В конце концов, MySQL и MongoDB являются GPL, поэтому, если у Mongo был какой-то волшебный код ввода-вывода, команда MySQL могла бы просто включить его в свою базу кода.

Люди видят работу MongoDB реального мира в значительной степени из-за того, что MongoDB позволяет вам запрашивать другой способ, более разумный для вашей рабочей нагрузки.

Например, рассмотрите дизайн, который сохранял много информации о сложной сущности нормализованным образом. Это может легко использовать десятки таблиц в MySQL (или любой реляционной db) для хранения данных в нормальной форме, с множеством индексов, необходимых для обеспечения реляционной целостности между таблицами.

Теперь рассмотрим тот же дизайн с хранилищем документов. Если все эти связанные таблицы подчинены основной таблице (и они часто бывают), то вы можете смоделировать данные таким образом, чтобы весь объект хранился в одном документе. В MongoDB вы можете хранить это как отдельный документ в одной коллекции. Именно здесь MongoDB начинает обеспечивать превосходную производительность.

В MongoDB для извлечения всего объекта вам необходимо выполнить:

  • Один индексный поиск в коллекции (при условии, что объект извлекается с помощью id)
  • Получить содержимое одной страницы базы данных (фактический двоичный json-документ)

Итак, поиск в b-tree и чтение двоичной страницы. Log (n) + 1 IO. Если индексы могут полностью находиться в памяти, тогда 1 IO.

В MySQL с 20 таблицами вы должны выполнить:

  • Один индексный поиск в корневой таблице (опять же, предполагая, что объект извлекается id)
  • С кластерным индексом мы можем предположить, что значения для корневой строки находятся в индексе
  • 20 + поиск диапазона (надеюсь, по индексу) для объекта pk value
  • Они, вероятно, не являются кластеризованными индексами, поэтому те же 20 + поиск данных, когда мы выясним, что представляют собой соответствующие дочерние строки.

Таким образом, общая сумма для mysql, даже если предположить, что все индексы находятся в памяти (что сложнее, чем в 20 раз больше), это около 20 запросов диапазона.

Эти поисковые запросы диапазона, вероятно, состоят из случайных IO - разные таблицы, безусловно, будут находиться в разных местах на диске, и возможно, что разные строки в одном и том же диапазоне в одной таблице для объекта могут не быть смежными (в зависимости от того, как объект обновлен и т.д.).

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

Именно так MongoDB может повысить производительность в некоторых случаях использования.

  • 33
    что если мы просто поместим одну главную таблицу в mysql?
  • 87
    @ariso: это оптимизация путем денормализации. Это может обеспечить повышение производительности. Однако, если вы сделаете это, вы отбросите свой чистый дизайн и всю мощь (не говоря уже о большинстве возможностей) реляционной базы данных. И это действительно работает, пока вы не достигнете предела столбца.
Показать ещё 6 комментариев
44

У вас есть concurrency, т.е. одновременные пользователи? Если вы просто запустите запрос в 1000 раз прямо, только с одним потоком, разница почти не будет. Слишком легко для этих двигателей:)

НО Я настоятельно рекомендую вам построить настоящий сеанс тестирования нагрузки, что означает использование инжектора, такого как JMeter, с 10, 20 или 50 пользователями в одно и то же время, чтобы вы могли увидеть разницу (попробуйте встроить этот код внутри веб-страница, которую может запросить JMeter).

Я просто сделал это сегодня на одном сервере (и простой коллекции/таблице), и результаты довольно интересны и удивительны (MongoDb был действительно быстрее при записи и чтении, по сравнению с движком MyISAM и движком InnoDb).

Это действительно должно быть частью вашего теста: concurrency и движок MySQL. Затем, дизайн/приложение схемы и приложения требуют, конечно, огромных требований, не зависящих от времени ответа. Дайте мне знать, когда вы получите результаты, мне также нужны материалы об этом!

  • 38
    Можете ли вы поделиться своими результатами?
  • 1
    Да, результаты по этому будут очень полезны
Показать ещё 1 комментарий
17

Источник: https://github.com/webcaetano/mongo-mysql

10 строк

mysql insert: 1702ms
mysql select: 11ms

mongo insert: 47ms
mongo select: 12ms

100 строк

mysql insert: 8171ms
mysql select: 10ms

mongo insert: 167ms
mongo select: 60ms

1000 строк

mysql insert: 94813ms (1.58 minutes)
mysql select: 13ms

mongo insert: 1013ms
mongo select: 677ms

10.000 строк

mysql insert: 924695ms (15.41 minutes)
mysql select: 144ms

mongo insert: 9956ms (9.95 seconds)
mongo select: 4539ms (4.539 seconds)
  • 71
    15 минут, чтобы вставить 10000 строк? Это очень анемичная база данных MySQL. По моему опыту, если такая операция длится 1 с, мой телефон загорается с жалобами. :)
  • 0
    Xtreme Biker взгляните на ссылку. Я отправил тест от других людей с другими настройками.
Показать ещё 15 комментариев
14

man,, ответ заключается в том, что вы в основном тестируете PHP, а не базу данных.

не утруждайте себя повторением результатов, будь то комментирование печати или нет. там кусок времени.

   foreach ($cursor as $obj)
    {
        //echo $obj["thread_title"] . "<br><Br>";
    }

в то время как другой кусок тратится на кучу rand-чисел.

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000) ;

    }
    return $numbers;
}

то theres основное различие b/w implode и in.

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

$m = new Mongo();

vs

$db = new AQLDatabase();

поэтому ваш 101% быстрее может оказаться на 1000% быстрее для базового запроса, лишенного джаза.

urghhh.

  • 4
    Естественно, практика кодирования может иметь большое значение в любой ситуации, но это не характерно для любого типа языка, API или расширения. генерация случайных чисел перед запуском таймера будет иметь значение, но большую часть времени в этом процессе, несомненно, составляют транзакции базы данных. генерация случайных чисел тривиальна, а базы данных SQL и NoSQL - нет.
  • 1
    не выбирайте номер ранда. очевидно, вы пропустили создание соединения каждый раз. все проблемы сводятся к тестированию чего-то другого, чем предполагалось.
Показать ещё 3 комментария
4

https://github.com/reoxey/benchmark

тест

сравнение скорости MySQL и MongoDB в GOLANG1.6 и PHP5

используемая для эталона: DELL cpu i5 4th gen 1.70Ghz * 4 ram 4GB GPU-RAM 2GB

Сравнение скорости RDBMS vs NoSQL для INSERT, SELECT, UPDATE, DELETE, выполняющих различное количество строк. 10,100,1000,10000,100000,1000000.

Язык, используемый для выполнения: PHP5 и самый быстрый язык Google GO 1.6

________________________________________________
GOLANG with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      1.195444ms
100                     6.075053ms
1000                    47.439699ms
10000                   483.999809ms
100000                  4.707089053s
1000000                 49.067407174s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 872.709µs


        SELECT & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 20.717354746s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 2.309209968s
100000                  257.411502ms
10000                   26.73954ms
1000                    3.483926ms
100                     915.17µs
10                      650.166µs


            DELETE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 6.065949ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


________________________________________________
GOLANG with MongoDB
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      2.067094ms
100                     8.841597ms
1000                    106.491732ms
10000                   998.225023ms
100000                  8.98172825s
1000000                 1m 29.63203158s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 5.251337439s


        FIND & DISPLAY (with index declared)
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 21.540603252s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1                       1.330954ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

________________________________________________
PHP5 with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
 10                     0.0040680000000001s
 100                    0.011595s
 1000                   0.049718s
 10000                  0.457164s
 100000                 4s
 1000000                42s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
 1000000                <1s


            SELECT & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
  1000000               20s
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

________________________________________________
PHP5 with MongoDB 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      0.065744s
100                     0.190966s
1000                    0.2163s
10000                   1s
100000                  8s
1000000                 78s


            FIND
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 <1s


            FIND & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 7s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 9s
  • 0
    myisam не innodb, а также какая версия mongodb и механизм хранения?
  • 0
    важно указать версии MySQL и MongoDB.
Показать ещё 1 комментарий
2

Вот небольшое исследование, которое изучало RDBMS vs NoSQL с использованием MySQL против Mongo, выводы были встроены в ответ @Sean Reilly. Короче говоря, преимущество исходит от дизайна, а не от некоторой разницы в скорости. Вывод на стр. 35-36:

RDBMS vs NoSQL: сравнение производительности и масштабирования

Проект тестировал, анализировал и сравнивал производительность и масштабируемость двух типов баз данных. Проведенные эксперименты включали запуская разные числа и типы запросов, некоторые более сложные, чем другие, с тем чтобы проанализировать, как нагрузки. Наиболее важным фактором в этом случае был тип запроса поскольку MongoDB может обрабатывать более сложные запросы быстрее из-за более простая схема при жертве дублирования данных, означающая, что База данных NoSQL может содержать большое количество дубликатов данных. Несмотря на то что можно было бы использовать схему, непосредственно перенесенную из СУБД. исключить преимущество базовых представлений данных MongoDB поддокументы, позволяющие использовать меньше запросов к база данных как таблицы были объединены. Несмотря на увеличение производительности, которое MongoDB имел над MySQL в этих сложных запросах, когда эталон смоделировал запрос MySQL аналогично сложному запросу MongoDB используя вложенные SELECTs MySQL выполнил наилучшее, хотя при более высоких числах соединений, которые оба ведут себя аналогично. Последний тип запроса который был сложным запросом, содержащим два JOINS, и Подзапрос показал преимущество MongoDB над MySQL из-за его использования. вложенные документы Это преимущество достигается за счет дублирования данных что приводит к увеличению размера базы данных. Если такие запросы типичный в приложении, тогда важно рассмотреть NoSQL базы данных как альтернативы при принятии учитывайте стоимость хранения и размер памяти в результате увеличения размер базы данных.

-4

На одном сервере MongoDb не будет быстрее, чем mysql MyISAM для чтения и записи, учитывая таблицу/документ размеры от 1 ГБ до 20 ГБ.
MonoDB будет быстрее на кластерах Parallel Reduce on Multi- Node, где Mysql не может масштабироваться горизонтально.

  • 5
    Можете ли вы предоставить некоторые доказательства или более подробную информацию, подтверждающую это?
  • 0
    Не может масштабироваться по горизонтали? Как насчет NDB? DRBD поддержал MySQL?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню