MySQL против MongoDB 1000 читает - PullRequest
292 голосов
/ 14 марта 2012

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

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


Примечание:

  • У меня есть двухъядерный + (2 потока) i7 CPU и 4 ГБ оперативной памяти
  • У меня есть 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;
}
?>

Ответы [ 7 ]

604 голосов
/ 14 марта 2012

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

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

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

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

В MongoDB, чтобы получить всю сущность, вы должны выполнить:

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

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

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

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

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

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

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

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

54 голосов
/ 02 апреля 2012

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

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

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

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

31 голосов
/ 16 сентября 2015

Источник: 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)
19 голосов
/ 02 января 2014

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

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

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

, в то время как другой кусок тратит на то, чтобы собрать кучу рандов.

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

$m = new Mongo();

против

$db = new AQLDatabase();

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

urghhh.

14 голосов
/ 06 июня 2016

https://github.com/reoxey/benchmark

тест производительности

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

, используемой для тестирования: процессор DELLi5 4-го поколения 1,70 ГГц * 4 ОЗУ 4 ГБ ОЗУ GPU 2 ГБ

Сравнение скорости СУРБД с NoSQL для INSERT, SELECT, UPDATE, DELETE при выполнении разного количества строк 10 100 100 000 100 000 100 000 100 000

Язык, используемый для исполнения: 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
4 голосов
/ 11 апреля 2017

Вот небольшое исследование , в котором исследовались СУБД и NoSQL с использованием MySQL против Mongo, выводы были в соответствии с ответом @Sean Reilly.Короче говоря, выгода от дизайна, а не от некоторой разницы в скорости.Заключение на стр. 35-36:

СУБД и NoSQL: сравнение производительности и масштабирования

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

0 голосов
/ 04 октября 2013

На одном сервере MongoDb не будет работать быстрее MySQL в MySQL как при чтении, так и при записи, поскольку размеры таблиц / документов малы - от 1 ГБ до 20 ГБ.
При параллельном уменьшении в кластерах с несколькими узлами скорость MonoDB будет вышегде Mysql НЕ может масштабироваться по горизонтали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...