Собственно, сегодня был запощен топик "Сравниваем производительность MongoDB и MySQL на простом примере", в котором указывалось, что MongoDB превышает по производительности MySQL в разы. Хех, когда такое пишут — я сразу лезу проверять и сомневаться. Я полез в исходники оригинального теста (спасибо за публикацию). И как оказалось автор оригинального топика сделал ошибку в три символа и на самом деле не все так:

На графике — число операций в секунду, (больше — лучше), шкала логарифмическая.
Последняя строка — то, что тестировал автор оригинального топика (неправильное, не в критику — все мы ошибаемся и учимся).
А теперь подробнее об ошибке...
Итак, ошибка оригинала была в том, что он делал SELECT так:
что возвращало Cursor(!), но не сам объект. То есть обращение к базе не происходит (или по крайней мере чтения данных не происходит). А вот что надо было:
Если бы автор проверял бы, что сохраненное значение (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ах
В комментах 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 диск обычный.»
И интереса ради добавлена Cassandra + pycassa (под win32) — сразу скажу — с ней у меня никакого опыта и много непонятного (.remove() не удаляет записи, а только очищает их, сами они остаются… + eventual consistency — оооооооочень трудно тестировать!) — полное прыгание с бубном в темноте, так что считайте просто развлекательным тестом.


Йои Хаджи,
вид с Хабра
- В оригинале: MongoDB быстрее MySQL пишет в 1.5 раза (ДА, правда у меня в 3 раза)
- В оригинале: MongoDB быстрее MySQL читает в 10 раз (НЕТ, на самом деле — MongoDB примерно на равных плюс-минус 10-30%)
- InnoDB vs MyISAM — плюс-минус (в оригинале не тестировалось)

На графике — число операций в секунду, (больше — лучше), шкала логарифмическая.
Последняя строка — то, что тестировал автор оригинального топика (неправильное, не в критику — все мы ошибаемся и учимся).
А теперь подробнее об ошибке...
Итак, ошибка оригинала была в том, что он делал 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 диск обычный.»
Выводы:
- На запись MongoDB быстрее, если использовать как key-value storage;
- Чтение примерно одинаково происходит;
- Обе системы — вполне приличные, никто не устарел, никто никого не убил, явного проигрывающего нет.
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')

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