Для теста использовал nodejs. Библиотеки для СУБД под nodejs (драйвера):
> ClickHouse
> MongoDB
Тестировал на железе:
i5-3570
8gb DDR3 1333 MHz Kingston
CSSD-N128GB3-BK
OS: Linux Mint 18
Перед началом теста поставил ClickHouse и MongoDB со стандартными настройками. Создал коллекцию в MongoDB «testCollections» и таблицу в ClickHouse «test» с движком MergeTree. Вот структура таблицы test в ClickHouse (в MongoDB структура динамическая):
create table test (event_date Date DEFAULT toDate(event_time), event_time DateTime DEFAULT now(), number UInt64, text String, month String) engine = MergeTree(event_date, (event_time, number, text, month), 8192);
Поля event_* для дат.
number — для случайного числа.
text — для случайного текста.
month — для случайного месяца.
В MongoDB буду тоже вставлять подобные данные с такой же структурой.
И вот можно начинать тест. Тестовые данные буду делать на «лету», то есть вставлять данные и смотреть результаты выполнения вставки в миллисекундах. В тесте не будет update так как в ClickHouse нет данной операции.
Структура данных для вставки:
MongoDB
[
{
event_date: '2017-01-29',
event_time: '2017-01-29 16:00:40',
number: 3,
text: 'sequi voluptatibus labore',
month: 'December'
},
...
]
ClickHouse
[
[
'2017-01-29',
'2017-01-29 16:00:40',
1,
'Et omnis consequatur id eaque suscipit error sed at. Eos ut omnis corporis unde. Tenetur ...',
'July'
],
...
]
Итак начнем.
Объем данных: 500 тыс. записей
В данном тесте будем вставлять и выбирать данные.
— Вставка в базу данных.
MongoDB:
![image](http://www.picshare.ru/uploads/170129/rN6x3UDGto.jpg)
Вставка заняла ~8289 ms.
ClickHouse:
![image](http://www.picshare.ru/uploads/170129/y0t3371Qj4.jpg)
Вставка заняла ~17375 ms.
Итого 17375-8289 = 9086 ms. MongoDB быстрее вставляет данные примерно в 2 раза чем ClickHouse.
— Выбираем данные
Выбирать будем сколько раз месяц «December» повторяется в таблице (коллекции).
MongoDB. Запрос:
db.testCollections.aggregate([
{
"$group" : {
_id : "$month", count:{
$sum:1
}
}
}
])
Результат 300 ms:
![image](http://www.picshare.ru/uploads/170129/6r4vw7EpR1.jpg)
ClickHouse. Запрос:
SELECT month, count() AS count FROM test GROUP BY month;
Результат 42 ms:
![image](http://www.picshare.ru/uploads/170129/qU3uIvwUo8.jpg)
Итого 300-42 = 258 ms. ClickHouse примерно в 7 раз быстрее выбирает данные с группировкой чем MongoDB.
Давайте сделаем еще простой select с limit 20.
MongoDB:
db.testCollections.find().limit(20);
Результат 13 ms:
![image](http://www.picshare.ru/uploads/170129/L2c4iVgGzT.jpg)
ClickHouse:
SELECT * FROM test limit 20;
Результат 24 ms:
![image](http://www.picshare.ru/uploads/170129/WA5vuo8G2Q.jpg)
Итого при select с limit 20 ClickHouse затратил примерно в 2-е больше времени чем MongoDB.
Давайте умножим данные в 10 раз и повторим тест на выборку данных.
Объем данных: 5 млн. записей
В данном тесте будем выбирать данные (то есть данные описанные выше уже вставлены в обе БД).
Результат count в обеих БД:
![image](http://www.picshare.ru/uploads/170129/Sv4K3sa1X9.jpg)
— Выбираем данные
Те же запросы с группировкой. MongoDB:
![image](http://www.picshare.ru/uploads/170129/IgGVW0u0o5.jpg)
Время выборки 3145 ms.
ClickHouse:
![image](http://www.picshare.ru/uploads/170129/xwLX1zsLh3.jpg)
Время выборки 112 ms.
ClickHouse при данном объеме данных в десятки раз быстрее. Обычный select с limit 20 прошел так же как и при 500 тыс. записей.
Давайте еще умножим данные в 10 раз и повторим тест на выборку данных. (что-то я вставил на 500 тыс. записей больше, будет 50 500 000 записей).
Объем данных: 50,5 млн. записей
Результат count в обеих БД:
![image](http://www.picshare.ru/uploads/170129/Y09i8MJOX3.jpg)
— Выбираем данные
Те же запросы с группировкой. MongoDB:
Клиент mongodb для nodejs отвалился через 35009 ms. Вот результат из GUI клиента для работы с MongoDB:
![image](http://www.picshare.ru/uploads/170129/VWQt4jXx50.jpg)
Время выборки 1m 12.571 s.
ClickHouse:
![image](http://www.picshare.ru/uploads/170129/TqQ3qU7eko.jpg)
Время выборки 931 ms.
ClickHouse явно лидирует.
Резюме
ClickHouse отлично подходит для проектов с BigData. Скорость выборки впечатляет. Данная СУБД хороший выбор для хранения данных связанных аналитической информацией.
Проект с тестами: посмотреть.
Комментарии (19)
webmasterx
30.01.2017 06:02+3В монге не было ни одного индекса? И в clickhouse тоже (если они там вообще есть)? И запросы на выборки довольно узкие. надо бы добавить для наглядности
saterenko
30.01.2017 11:27ClickHouse колоночная база данных, там как бы по-умолчанию есть «индекс» по каждому из столбцов. Т.е. при выборке из статьи используется индекс по месяцу.
novoselov
30.01.2017 09:44+8Попробовали insert — MongoDB быстрее, нет не подходит.
Попробовали select — MongoDB быстрее, нет не подходит.
Попробовали aggregate без индексов — MongoDB медленнее, вот это и будем сравнивать!
В чем смысл статьи?frux
30.01.2017 09:57Тащем-то нет:
Попробовали insert — MongoDB быстрее
Попробовали select — MongoDB медленнее
Заключение: «ClickHouse отлично подходит для проектов с BigData. Скорость выборки впечатляет. Данная СУБД хороший выбор для хранения данных связанных аналитической информацией.»
В заключении явно указано, что вставка – не сильная сторона ClickHouse'a в отличие от выборки. Значит он отлично подходит там, где надо много и часто выбирать.fuCtor
30.01.2017 10:39В заключении явно указано, что вставка – не сильная сторона ClickHouse'a в отличие от выборки. Значит он отлично подходит там, где надо много и часто выбирать.
В документации четко прописано как рекомендуется его использовать, в частности, большие но не частые вставки (пара вставок в секунду норм). Выборки тоже не частые, но на больших срезах. Тот же пример select с limit, где limit никак не влияет на время исполнения по факту, т.к. данные вычитываются полностью.
zBit
30.01.2017 17:14aggregate без индексов медленнее до первого изменения проекции, т.е. если будет aggregate и первым пайпом будет $match, то выборка будет осуществляться с использованием индексов.
xhumanoid
31.01.2017 12:26+1причем стоит добавить, что aggregate с последующим «count: {$sum: 1}» работает на порядки медленнее, чем делать find(...).count() из-за особенностей реализации, разница в некоторых случаях у меня была миллисекунды-секунды vs минуты.
index используется в обоих случаях, но по разному
count может пробежаться по индексу и просто посчитать количество входов
агрегаты всегда производят материализацию объектов найденых, а уже потом только прибавляют 1, в итоге получаем fetch и disk io.
поэтому сравнения вообще ни о чём =)
hagen1778
30.01.2017 09:51+4Не указано как именно осуществлялась вставка. В документации CH указано, что оптимальным считается вставка батчами по 100к записей.
wladyspb
30.01.2017 15:48Обычная практика у нас — накопление очереди в редисе и отправка инсерта раз в минуту или чаще. 5к строк вставляются без проблем одним пакетом (данных много, включая строковые типа userAgent). 50к уже многовато(для наших запросов).
bormotov
30.01.2017 10:19+4статья хорошо показывает два простых момента
1. тексты нужно уметь делать.
2. результат нужно уметь удобно представить.
youROCK
Всего 50 млн строк за секунду? Вроде как ClickHouse должен примерно на 8 ядрах успевать сканировать 1 миллиард. Вы, вероятно, вставляли строки с именами месяцев «как есть» вместо использования dict(...), например, или просто номеров месяца. Попробуйте с uint8, должно стать намного быстрее. Ну и что такое 50 млн записей, кто на таком малом объеме тестирует :)? И еще можно попробовать использовать семплирование данных при выборке, это должно серьезно ускорить выборки без особой потери в точности.
Coocos
Со строковыми типами ClickHouse работает в разы медленней чем с числами.