Перейти к основному содержимому
Перейти к основному содержимому

Сравнение ClickHouse Cloud и BigQuery

Организация ресурсов

Способ организации ресурсов в ClickHouse Cloud схож с иерархией ресурсов BigQuery. Мы описываем конкретные различия ниже на основе следующей диаграммы, показывающей иерархию ресурсов ClickHouse Cloud:

Организация ресурсов

Организации

Подобно BigQuery, организации являются корневыми узлами в иерархии ресурсов ClickHouse Cloud. Первый пользователь, которого вы настраиваете в своей учетной записи ClickHouse Cloud, автоматически назначается в организацию, принадлежащую этому пользователю. Пользователь может приглашать других пользователей в организацию.

Проекты BigQuery против служб ClickHouse Cloud

Внутри организаций вы можете создавать службы, которые в некоторой степени эквивалентны проектам BigQuery, поскольку хранимые данные в ClickHouse Cloud ассоциированы со службой. В ClickHouse Cloud доступно несколько типов служб. Каждая служба ClickHouse Cloud развертывается в конкретном регионе и включает:

  1. Группу вычислительных узлов (в настоящее время 2 узла для службы уровня разработки и 3 для службы уровня производства). Для этих узлов ClickHouse Cloud поддерживает вертикальное и горизонтальное масштабирование, как вручную, так и автоматически.
  2. Папку объектного хранения, где служба хранит все данные.
  3. Endpoint (или несколько endpoint, созданных через консоль UI ClickHouse Cloud) - URL службы, который вы используете для подключения к службе (например, https://dv2fzne24g.us-east-1.aws.clickhouse.cloud:8443)

Наборы данных BigQuery против баз данных ClickHouse Cloud

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

Папки BigQuery

В ClickHouse Cloud в данный момент отсутствует концепция, эквивалентная папкам BigQuery.

Резервирование слотов и квоты BigQuery

Как и резервации слотов в BigQuery, вы можете настраивать вертикальное и горизонтальное автоматическое масштабирование в ClickHouse Cloud. Для вертикального автоматического масштабирования вы можете установить минимум и максимум для объема памяти и ядер CPU вычислительных узлов службы. Служба будет масштабироваться по мере необходимости в этих пределах. Эти настройки также доступны во время начального процесса создания службы. Каждый вычислительный узел в службе имеет одинаковый размер. Вы можете изменить количество вычислительных узлов в службе с помощью горизонтального масштабирования.

Более того, подобно квотам BigQuery, ClickHouse Cloud предлагает управление параллельностью, лимиты использования памяти и планирование I/O, позволяя пользователям изолировать запросы в классы нагрузки. Устанавливая лимиты на общие ресурсы (ядра CPU, DRAM, ввод-вывод диска и сети) для конкретных классов нагрузки, он гарантирует, что эти запросы не влияют на другие критически важные бизнес-запросы. Управление параллельностью предотвращает переподписку потоков в сценариях с высоким количеством параллельных запросов.

ClickHouse отслеживает размеры байтов выделения памяти на уровне сервера, пользователя и запроса, что позволяет гибко устанавливать лимиты использования памяти. Переполнение памяти позволяет запросам использовать дополнительную свободную память сверх гарантированной памяти, обеспечивая при этом лимиты памяти для других запросов. Кроме того, использование памяти для агрегации, сортировки и JOIN-слов можно ограничить, позволяя использовать внешние алгоритмы, когда лимит памяти превышен.

Наконец, планирование I/O позволяет пользователям ограничивать локальные и удаленные доступы к дискам для классов нагрузки на основе максимальной пропускной способности, активных запросов и политики.

Разрешения

ClickHouse Cloud контролирует доступ пользователей в двух местах: через консоль облака и через базу данных. Доступ к консоли управляется через пользовательский интерфейс clickhouse.cloud. Доступ к базе данных управляется через учетные записи пользователей баз данных и роли. Кроме того, пользователям консоли могут быть назначены роли в рамках базы данных, которые позволяют пользователю консоли взаимодействовать с базой данных через нашу SQL консоль.

Типы данных

ClickHouse предлагает более детальную точность относительно чисел. Например, BigQuery предлагает числовые типы INT64, NUMERIC, BIGNUMERIC и FLOAT64. В отличие от этого, ClickHouse предлагает несколько типов точности для десятичных, плавающих и целых чисел. С этими типами данных пользователи ClickHouse могут оптимизировать выделение памяти и хранение, что приводит к более быстрым запросам и меньшему потреблению ресурсов. Ниже мы сопоставляем эквивалентные типы ClickHouse для каждого типа BigQuery:

BigQueryClickHouse
ARRAYArray(t)
NUMERICDecimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S)
BIG NUMERICDecimal256(S)
BOOLBool
BYTESFixedString
DATEDate32 (с более узким диапазоном)
DATETIMEDateTime, DateTime64 (узкий диапазон, высокая точность)
FLOAT64Float64
GEOGRAPHYGeo Data Types
INT64UInt8, UInt16, UInt32, UInt64, UInt128, UInt256, Int8, Int16, Int32, Int64, Int128, Int256
INTERVALNA - поддерживается как выражение или через функции
JSONJSON
STRINGString (bytes)
STRUCTTuple, Nested
TIMEDateTime64
TIMESTAMPDateTime64

При выборе среди нескольких типов ClickHouse учитывайте фактический диапазон данных и выбирайте минимально необходимый. Также рекомендуем использовать подходящие кодеки для дальнейшего сжатия.

Техники ускорения запросов

Первичные и внешние ключи и первичный индекс

В BigQuery таблицы могут иметь ограничения первичного и внешнего ключа. Обычно первичные и внешние ключи используются в реляционных базах данных для обеспечения целостности данных. Значение первичного ключа, как правило, уникально для каждой строки и не может быть NULL. Каждое значение внешнего ключа в строке должно присутствовать в столбце первичного ключа основной таблицы или быть NULL. В BigQuery эти ограничения не принудительно выполняются, но оптимизатор запросов может использовать эту информацию для улучшения оптимизации запросов.

В ClickHouse таблица также может иметь первичный ключ. Как и в BigQuery, ClickHouse не требует уникальности значений столбца первичного ключа таблицы. В отличие от BigQuery, данные таблицы в ClickHouse хранятся на диске упорядоченные по значениям столбца(ов) первичного ключа. Оптимизатор запросов использует этот порядок сортировки, чтобы предотвратить повторную сортировку, минимизировать использование памяти для соединений и включить короткое замыкание для операторов LIMIT. В отличие от BigQuery, ClickHouse автоматически создает средний (разреженный) первичный индекс на основе значений столбца первичного ключа. Этот индекс используется для ускорения всех запросов, которые содержат фильтры на столбцах первичного ключа. На данный момент ClickHouse не поддерживает ограничения внешнего ключа.

Вторичные индексы (Доступны только в ClickHouse)

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

  • Индекс фильтра Блума:
    • Используется для ускорения запросов с условиями равенства (например, =, IN).
    • Использует вероятностные структуры данных, чтобы определить, существует ли значение в блоке данных.
  • Индекс токенизированного фильтра Блума:
    • Похож на индекс фильтра Блума, но используется для токенизированных строк и подходит для запросов полнотекстового поиска.
  • Min-Max индекс:
    • Сохраняет минимальные и максимальные значения столбца для каждой части данных.
    • Помогает пропустить чтение частей данных, которые не входят в заданный диапазон.

Поисковые индексы

Аналогично поисковым индексам в BigQuery, индексы полнотекстового поиска могут быть созданы для таблиц ClickHouse на столбцах со строковыми значениями.

Векторные индексы

Совсем недавно BigQuery представил векторные индексы как предварительную функцию GA. Аналогично, ClickHouse имеет экспериментальную поддержку индексов для ускорения случаев поиска векторов.

Партиционирование

Как и в BigQuery, ClickHouse использует партиционирование таблиц для повышения производительности и управляемости больших таблиц, разделяя таблицы на более мелкие, более управляемые части, называемые партициями. Мы подробно описали партиционирование в ClickHouse здесь.

Кластеризация

С помощью кластеризации BigQuery автоматически сортирует данные таблицы на основе значений нескольких заданных столбцов и размещает их в оптимально размере блоков. Кластеризация улучшает производительность запросов, позволяя BigQuery лучше оценивать стоимость выполнения запроса. С кластеризованными столбцами запросы также исключают сканирование ненужных данных.

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

Материализованные представления

Как BigQuery, так и ClickHouse поддерживают материализованные представления – предвычисленные результаты на основе результата запроса трансформации для повышения производительности и эффективности.

Запросы к материализованным представлениям

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

В ClickHouse материализованные представления можно запрашивать только напрямую. Однако, по сравнению с BigQuery (в котором материализованные представления автоматически обновляются в течение 5 минут после изменения в базовых таблицах, но не чаще чем раз в 30 минут), материализованные представления всегда синхронизированы с базовой таблицей.

Обновление материализованных представлений

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

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

Транзакции

В отличие от ClickHouse, BigQuery поддерживает многооперационные транзакции внутри одного запроса или через несколько запросов при использовании сессий. Многооперационная транзакция позволяет вам выполнять операции мутации, такие как вставка или удаление строк в одной или нескольких таблицах, и либо зафиксировать, либо откатить изменения атомарно. Многооперационные транзакции находятся на дорожной карте ClickHouse на 2024 год.

Агрегатные функции

По сравнению с BigQuery, ClickHouse предлагает значительно больше встроенных агрегатных функций:

Источники данных и форматы файлов

По сравнению с BigQuery, ClickHouse поддерживает значительно больше форматов файлов и источников данных:

  • ClickHouse имеет нативную поддержку загрузки данных в 90+ форматов файлов из практически любого источника данных.
  • BigQuery поддерживает 5 форматов файлов и 19 источников данных.

Возможности SQL языка

ClickHouse предоставляет стандартный SQL с множеством расширений и улучшений, которые делают его более удобным для аналитических задач. Например, SQL ClickHouse поддерживает лямбда-функции и функции высшего порядка, поэтому вам не нужно разбирать/взрывать массивы при применении преобразований. Это является большим преимуществом по сравнению с другими системами, такими как BigQuery.

Массивы

По сравнению с 8 функциями массивов BigQuery, ClickHouse имеет более 80 встроенных функций массива для элегантного и простого моделирования и решения широкого диапазона задач.

Типичный шаблон проектирования в ClickHouse – использовать агрегатную функцию groupArray для (временного) преобразования определенных значений строк таблицы в массив. Этот массив затем может быть удобно обработан через функции массива, а результат может быть обратно преобразован в отдельные строки таблицы с помощью агрегатной функции arrayJoin.

Поскольку SQL ClickHouse поддерживает лямбда-функции высшего порядка, многие сложные операции с массивами могут быть выполнены простым вызовом одной из встроенных функций массива высшего порядка, вместо того чтобы временно преобразовывать массивы обратно в таблицы, как это часто требуется в BigQuery, например, для фильтрации или объединения массивов. В ClickHouse эти операции являются всего лишь простым вызовом функций высшего порядка arrayFilter и arrayZip соответственно.

Ниже мы приводим сопоставление операций с массивами от BigQuery к ClickHouse:

BigQueryClickHouse
ARRAY_CONCATarrayConcat
ARRAY_LENGTHlength
ARRAY_REVERSEarrayReverse
ARRAY_TO_STRINGarrayStringConcat
GENERATE_ARRAYrange

Создание массива с одним элементом для каждой строки в подзапросе

BigQuery

ARRAY функция

SELECT ARRAY
  (SELECT 1 UNION  ALL
   SELECT 2 UNION ALL
   SELECT 3) AS new_array;

/*-----------*
 | new_array |
 +-----------+
 | [1, 2, 3] |
 *-----------*/

ClickHouse

aggregate function groupArray

SELECT groupArray(*) AS new_array
FROM
(
    SELECT 1
    UNION ALL
    SELECT 2
    UNION ALL
    SELECT 3
)
   ┌─new_array─┐
1. │ [1,2,3]   │
   └───────────┘

Преобразование массива в набор строк

BigQuery

UNNEST оператор

SELECT *
FROM UNNEST(['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred'])
  AS element
WITH OFFSET AS offset
ORDER BY offset;

/*----------+--------*
 | element  | offset |
 +----------+--------+
 | foo      | 0      |
 | bar      | 1      |
 | baz      | 2      |
 | qux      | 3      |
 | corge    | 4      |
 | garply   | 5      |
 | waldo    | 6      |
 | fred     | 7      |
 *----------+--------*/

ClickHouse

ARRAY JOIN оператор

WITH ['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred'] AS values
SELECT element, num-1 AS offset
FROM (SELECT values AS element) AS subquery
ARRAY JOIN element, arrayEnumerate(element) AS num;

/*----------+--------*
 | element  | offset |
 +----------+--------+
 | foo      | 0      |
 | bar      | 1      |
 | baz      | 2      |
 | qux      | 3      |
 | corge    | 4      |
 | garply   | 5      |
 | waldo    | 6      |
 | fred     | 7      |
 *----------+--------*/

Возврат массива дат

BigQuery

GENERATE_DATE_ARRAY функция

SELECT GENERATE_DATE_ARRAY('2016-10-05', '2016-10-08') AS example;

/*--------------------------------------------------*
 | example                                          |
 +--------------------------------------------------+
 | [2016-10-05, 2016-10-06, 2016-10-07, 2016-10-08] |
 *--------------------------------------------------*/

range + arrayMap функции

ClickHouse

SELECT arrayMap(x -> (toDate('2016-10-05') + x), range(toUInt32((toDate('2016-10-08') - toDate('2016-10-05')) + 1))) AS example

   ┌─example───────────────────────────────────────────────┐
1. │ ['2016-10-05','2016-10-06','2016-10-07','2016-10-08'] │
   └───────────────────────────────────────────────────────┘

Возврат массива временных меток

BigQuery

GENERATE_TIMESTAMP_ARRAY функция

SELECT GENERATE_TIMESTAMP_ARRAY('2016-10-05 00:00:00', '2016-10-07 00:00:00',
                                INTERVAL 1 DAY) AS timestamp_array;

/*--------------------------------------------------------------------------*
 | timestamp_array                                                          |
 +--------------------------------------------------------------------------+
 | [2016-10-05 00:00:00+00, 2016-10-06 00:00:00+00, 2016-10-07 00:00:00+00] |
 *--------------------------------------------------------------------------*/

ClickHouse

range + arrayMap функции

SELECT arrayMap(x -> (toDateTime('2016-10-05 00:00:00') + toIntervalDay(x)), range(dateDiff('day', toDateTime('2016-10-05 00:00:00'), toDateTime('2016-10-07 00:00:00')) + 1)) AS timestamp_array

Query id: b324c11f-655b-479f-9337-f4d34fd02190

   ┌─timestamp_array─────────────────────────────────────────────────────┐
1. │ ['2016-10-05 00:00:00','2016-10-06 00:00:00','2016-10-07 00:00:00'] │
   └─────────────────────────────────────────────────────────────────────┘

Фильтрация массивов

BigQuery

Требует временного преобразования массивов обратно в таблицы через UNNEST оператор

WITH Sequences AS
  (SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
   UNION ALL SELECT [2, 4, 8, 16, 32] AS some_numbers
   UNION ALL SELECT [5, 10] AS some_numbers)
SELECT
  ARRAY(SELECT x * 2
        FROM UNNEST(some_numbers) AS x
        WHERE x < 5) AS doubled_less_than_five
FROM Sequences;

/*------------------------*
 | doubled_less_than_five |
 +------------------------+
 | [0, 2, 2, 4, 6]        |
 | [4, 8]                 |
 | []                     |
 *------------------------*/

ClickHouse

arrayFilter функция

WITH Sequences AS
    (
        SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
        UNION ALL
        SELECT [2, 4, 8, 16, 32] AS some_numbers
        UNION ALL
        SELECT [5, 10] AS some_numbers
    )
SELECT arrayMap(x -> (x * 2), arrayFilter(x -> (x < 5), some_numbers)) AS doubled_less_than_five
FROM Sequences;
   ┌─doubled_less_than_five─┐
1. │ [0,2,2,4,6]            │
   └────────────────────────┘
   ┌─doubled_less_than_five─┐
2. │ []                     │
   └────────────────────────┘
   ┌─doubled_less_than_five─┐
3. │ [4,8]                  │
   └────────────────────────┘

Объединение массивов

BigQuery

Требует временного преобразования массивов обратно в таблицы через UNNEST оператор

WITH
  Combinations AS (
    SELECT
      ['a', 'b'] AS letters,
      [1, 2, 3] AS numbers
  )
SELECT
  ARRAY(
    SELECT AS STRUCT
      letters[SAFE_OFFSET(index)] AS letter,
      numbers[SAFE_OFFSET(index)] AS number
    FROM Combinations
    CROSS JOIN
      UNNEST(
        GENERATE_ARRAY(
          0,
          LEAST(ARRAY_LENGTH(letters), ARRAY_LENGTH(numbers)) - 1)) AS index
    ORDER BY index
  );

/*------------------------------*
 | pairs                        |
 +------------------------------+
 | [{ letter: "a", number: 1 }, |
 |  { letter: "b", number: 2 }] |
 *------------------------------*/

ClickHouse

arrayZip функция

WITH Combinations AS
    (
        SELECT
            ['a', 'b'] AS letters,
            [1, 2, 3] AS numbers
    )
SELECT arrayZip(letters, arrayResize(numbers, length(letters))) AS pairs
FROM Combinations;
   ┌─pairs─────────────┐
1. │ [('a',1),('b',2)] │
   └───────────────────┘

Агрегация массивов

BigQuery

Требует преобразования массивов обратно в таблицы через UNNEST оператор

WITH Sequences AS
  (SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
   UNION ALL SELECT [2, 4, 8, 16, 32] AS some_numbers
   UNION ALL SELECT [5, 10] AS some_numbers)
SELECT some_numbers,
  (SELECT SUM(x)
   FROM UNNEST(s.some_numbers) AS x) AS sums
FROM Sequences AS s;

/*--------------------+------*
 | some_numbers       | sums |
 +--------------------+------+
 | [0, 1, 1, 2, 3, 5] | 12   |
 | [2, 4, 8, 16, 32]  | 62   |
 | [5, 10]            | 15   |
 *--------------------+------*/

ClickHouse

arraySum, arrayAvg, ... функция или любая из более чем 90 существующих имен агрегатных функций в качестве аргумента для функции arrayReduce

WITH Sequences AS
    (
        SELECT [0, 1, 1, 2, 3, 5] AS some_numbers
        UNION ALL
        SELECT [2, 4, 8, 16, 32] AS some_numbers
        UNION ALL
        SELECT [5, 10] AS some_numbers
    )
SELECT
    some_numbers,
    arraySum(some_numbers) AS sums
FROM Sequences;
   ┌─some_numbers──┬─sums─┐
1. │ [0,1,1,2,3,5] │   12 │
   └───────────────┴──────┘
   ┌─some_numbers──┬─sums─┐
2. │ [2,4,8,16,32] │   62 │
   └───────────────┴──────┘
   ┌─some_numbers─┬─sums─┐
3. │ [5,10]       │   15 │
   └──────────────┴──────┘