Так как колоночная СУБД ClickHouse (внутренняя разработка Яндекс) стала доступна каждому, решил использовать эту СУБД заместо MongoDB для хранения аналитических данных. Перед использованием сделал небольшой тест производительности и хочу поделиться результатами с IT сообществом.

Для теста использовал 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

Вставка заняла ~8289 ms.

ClickHouse:

image

Вставка заняла ~17375 ms.

Итого 17375-8289 = 9086 ms. MongoDB быстрее вставляет данные примерно в 2 раза чем ClickHouse.

— Выбираем данные

Выбирать будем сколько раз месяц «December» повторяется в таблице (коллекции).

MongoDB. Запрос:

db.testCollections.aggregate([
         {
            "$group" : {
                _id : "$month", count:{
                    $sum:1
                }
            }
        }
 ])

Результат 300 ms:

image

ClickHouse. Запрос:

SELECT month, count() AS count FROM test GROUP BY month;

Результат 42 ms:

image

Итого 300-42 = 258 ms. ClickHouse примерно в 7 раз быстрее выбирает данные с группировкой чем MongoDB.

Давайте сделаем еще простой select с limit 20.

MongoDB:

 db.testCollections.find().limit(20);


Результат 13 ms:

image

ClickHouse:

SELECT * FROM test limit 20;

Результат 24 ms:

image

Итого при select с limit 20 ClickHouse затратил примерно в 2-е больше времени чем MongoDB.

Давайте умножим данные в 10 раз и повторим тест на выборку данных.

Объем данных: 5 млн. записей


В данном тесте будем выбирать данные (то есть данные описанные выше уже вставлены в обе БД).
Результат count в обеих БД:

image

— Выбираем данные

Те же запросы с группировкой. MongoDB:

image

Время выборки 3145 ms.

ClickHouse:

image

Время выборки 112 ms.

ClickHouse при данном объеме данных в десятки раз быстрее. Обычный select с limit 20 прошел так же как и при 500 тыс. записей.

Давайте еще умножим данные в 10 раз и повторим тест на выборку данных. (что-то я вставил на 500 тыс. записей больше, будет 50 500 000 записей).

Объем данных: 50,5 млн. записей


Результат count в обеих БД:

image

— Выбираем данные

Те же запросы с группировкой. MongoDB:

Клиент mongodb для nodejs отвалился через 35009 ms. Вот результат из GUI клиента для работы с MongoDB:

image

Время выборки 1m 12.571 s.

ClickHouse:

image

Время выборки 931 ms.

ClickHouse явно лидирует.

Резюме


ClickHouse отлично подходит для проектов с BigData. Скорость выборки впечатляет. Данная СУБД хороший выбор для хранения данных связанных аналитической информацией.

Проект с тестами: посмотреть.
Поделиться с друзьями
-->

Комментарии (19)


  1. youROCK
    30.01.2017 02:38
    +5

    Всего 50 млн строк за секунду? Вроде как ClickHouse должен примерно на 8 ядрах успевать сканировать 1 миллиард. Вы, вероятно, вставляли строки с именами месяцев «как есть» вместо использования dict(...), например, или просто номеров месяца. Попробуйте с uint8, должно стать намного быстрее. Ну и что такое 50 млн записей, кто на таком малом объеме тестирует :)? И еще можно попробовать использовать семплирование данных при выборке, это должно серьезно ускорить выборки без особой потери в точности.


    1. Coocos
      30.01.2017 11:15

      Со строковыми типами ClickHouse работает в разы медленней чем с числами.


  1. webmasterx
    30.01.2017 06:02
    +3

    В монге не было ни одного индекса? И в clickhouse тоже (если они там вообще есть)? И запросы на выборки довольно узкие. надо бы добавить для наглядности


    1. saterenko
      30.01.2017 11:27

      ClickHouse колоночная база данных, там как бы по-умолчанию есть «индекс» по каждому из столбцов. Т.е. при выборке из статьи используется индекс по месяцу.


  1. novoselov
    30.01.2017 09:44
    +8

    Попробовали insert — MongoDB быстрее, нет не подходит.
    Попробовали select — MongoDB быстрее, нет не подходит.
    Попробовали aggregate без индексов — MongoDB медленнее, вот это и будем сравнивать!
    В чем смысл статьи?


    1. frux
      30.01.2017 09:57

      Тащем-то нет:
      Попробовали insert — MongoDB быстрее
      Попробовали select — MongoDB медленнее

      Заключение: «ClickHouse отлично подходит для проектов с BigData. Скорость выборки впечатляет. Данная СУБД хороший выбор для хранения данных связанных аналитической информацией.»

      В заключении явно указано, что вставка – не сильная сторона ClickHouse'a в отличие от выборки. Значит он отлично подходит там, где надо много и часто выбирать.


      1. fuCtor
        30.01.2017 10:39

        В заключении явно указано, что вставка – не сильная сторона ClickHouse'a в отличие от выборки. Значит он отлично подходит там, где надо много и часто выбирать.

        В документации четко прописано как рекомендуется его использовать, в частности, большие но не частые вставки (пара вставок в секунду норм). Выборки тоже не частые, но на больших срезах. Тот же пример select с limit, где limit никак не влияет на время исполнения по факту, т.к. данные вычитываются полностью.


    1. zBit
      30.01.2017 17:14

      aggregate без индексов медленнее до первого изменения проекции, т.е. если будет aggregate и первым пайпом будет $match, то выборка будет осуществляться с использованием индексов.


      1. xhumanoid
        31.01.2017 12:26
        +1

        причем стоит добавить, что aggregate с последующим «count: {$sum: 1}» работает на порядки медленнее, чем делать find(...).count() из-за особенностей реализации, разница в некоторых случаях у меня была миллисекунды-секунды vs минуты.

        index используется в обоих случаях, но по разному

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

        поэтому сравнения вообще ни о чём =)


  1. hagen1778
    30.01.2017 09:51
    +4

    Не указано как именно осуществлялась вставка. В документации CH указано, что оптимальным считается вставка батчами по 100к записей.


    1. wladyspb
      30.01.2017 15:48

      Обычная практика у нас — накопление очереди в редисе и отправка инсерта раз в минуту или чаще. 5к строк вставляются без проблем одним пакетом (данных много, включая строковые типа userAgent). 50к уже многовато(для наших запросов).


  1. bormotov
    30.01.2017 10:19
    +4

    статья хорошо показывает два простых момента

    1. тексты нужно уметь делать.
    2. результат нужно уметь удобно представить.


  1. onyxmaster
    30.01.2017 11:15
    +1

    Укажите, пожалуйста версии и того и другого.


  1. yusman
    30.01.2017 11:40
    +4

    Ждем сравнения производительности кислого со сладким.


    1. Botchal
      30.01.2017 12:45
      +3

      в многопоточном режиме


      1. Coocos
        30.01.2017 13:34
        +1

        Двух кластеров


  1. zBit
    30.01.2017 14:09
    +3

    Требую тестов с проиндексированным коллекциями в MongoDB.


    1. wladyspb
      30.01.2017 16:04

      Требую не сравнивать колоночные базы с документарными) Ещё бы сравнили редис с мускулом, и сказали что редис лучше, потому что быстрее)


      1. zBit
        30.01.2017 17:11
        +1

        Согласен, но для бОльшей объективности данного (не очень правильного, ИМХО) обзора нужны индексы в MongoDB.