CHYT 2.17

Рассказываем о главных обновлениях в новой версии CHYT

Для корректной работы требуется версия YTsaurus 24.1 и старше.

CHYT базируется на LTS релизах ClickHouse. До недавнего времени новые версии CHYT использовали 23.8, но в новой версии мы обновились до 24.8.

Полноэкранное изображение
Сравнение производительности в бенчмарке ClickBench 2.16 и 2.17 на кликах разных размеров.

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

Рекурсивные CTE

Начиная с версии 24.3 в ClickHouse начал переходить на новый анализатор запросов (подобнее о нём можно прочитать в оригинальной документации ClickHouse). Помимо фиксов различных ошибок предыдущего анализатора, появилась возможность реализации рекурсивных CTE.

Например, суммирование от 1 до 100:

WITH RECURSIVE test_table AS (
SELECT 1 AS number
UNION ALL
SELECT number + 1 FROM test_table WHERE number < 100
)
SELECT sum(number) FROM test_table;
Экспериментальная поддержка JOIN по неравенству

Начиная с версии ClickHouse 24.5 добавлена поддержка JOIN-таблиц по неравенству. На момент выпуска 24.8 данный функционал является экспериментальным и требуется явное указание включения настройки allow_experimental_join_condition:

SET allow_experimental_join_condition = 1;

SELECT
    lt.l_n
  ,rt.r_n
FROM
(
    SELECT
        1 as id
      ,number as l_n
    FROM numbers(1, 5)
) as lt
JOIN
(
    SELECT
        1 as id
      ,number as r_n
    FROM numbers(4, 6)
) rt
ON lt.id = rt.id AND lt.l_n > rt.r_n
PASTE JOIN

ClickHouse начал поддерживать новый тип JOIN: PASTE JOIN.

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

SELECT
    *
FROM
(
    SELECT
        number
      ,rand(100)
    FROM numbers(100)
    ORDER BY number
) lt
PASTE JOIN
(
    SELECT
        number
      ,rand(100)
    FROM numbers(100)
    ORDER BY number 
) rt
Конструкция QUALIFY

Раньше, если в запросе использовалась оконная функция и нужно было отфильтровать результат по ее значениям, единственным решением было, например, оборачивать эту конструкцию, например, в CTE и дальше фильтровать через WHERE:

SELECT
    id,
    sub_id,
    rank() OVER (PARTITION BY sub_id ORDER BY value DESC) as pos
FROM
(
    SELECT
        round(number / 100) as id
        ,round(number / 1000) as sub_id
        ,rand(100) as value
    FROM numbers(1000)
)
WHERE pos <= 3

Подобный запрос завершается с ошибкой

Window function rank() OVER (PARTITION BY sub_id ORDER BY value DESC) AS pos is found in WHERE in query

Однако, с версии 24.4 добавлена новая конструкция QUALIFY, позволяющая применить фильтрацию к сразу к результату в проекции:

SELECT
    id,
    sub_id,
    rank() OVER (PARTITION BY sub_id ORDER BY value DESC) as pos
FROM
(
    SELECT
        round(number / 100) as id
        ,round(number / 1000) as sub_id
        ,rand(100) as value
    FROM numbers(1000)
)
QUALIFY pos <= 3

Функция ConvertYsonToJson

Часть пользователей испытывали трудности с парсингом YSON, и мы добавили новую функцию преобразования YSON объекта в JSON. В прошлых релизах мы уже поддержали ClickHouse функции JSON_EXISTS, JSON_VALUE и JSON_QUERY.

SELECT
    '{a=[{c=xyz}; {c=qwe}]}' as my_yson,
    JSON_VALUE(ConvertYsonToJson(my_yson), '$.a[0].c') as json_value,
    JSON_QUERY(ConvertYsonToJson(my_yson), '$.a[0].c') as json_query,
    JSON_EXISTS(ConvertYsonToJson(my_yson), '$.a[0].c') as json_exists
#       my_yson                     json_value       json_query       json_exists
1       "{a=[{c=xyz}; {c=qwe}]}"    "xyz"            "[\"xyz\"]"      1

Поддержка выражения EXPLAIN

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

Например, конструкция EXPLAIN indexes=1 возвращает число строк и их вес, необходимый для выполнения запроса:

EXPLAIN indexes=1
SELECT
    count(*)
FROM `//home/clickbench/hits`
WHERE CounterID = 17
1       "Expression ((Project names + Projection))"
2       "  MergingAggregated"
3       "    ReadFromYT (Tables: [//home/clickbench/hits, ] )"
4       "    Indexes: "
5       "Type: KeyCondition"
6       "Row count: 12393569"
7       "Data weight: 112968682"
8       "Filtered row count: 87603928"
9       "Filtered data weight: 807044157"

Поддержка многопоточного INSERT

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

Сравнение скорости при разном количестве потоков на запись:

CREATE TABLE `//tmp/insert_table` 
ENGINE = YtTable()
AS
SELECT
    randomString(1024) as str
FROM numbers_mt(20000000)
SETTINGS max_insert_threads=1;
Полноэкранное изображение

Однако, стоит заметить, что не всегда скорость записи упирается в число writer’ов. В процессе записи, CHYT проводит преобразования в формат данных YTsaurus, что является CPU-интенсивной операцией. Также для скорости играет важную роль степень конкурентной нагрузки на диски. Поддержка многопоточной записи лишь убирает одно бутылочное горлышко.

Сборка HTTP‑header’ов в query_log

Мы добавили дополнительную колонку http_headers в Query log, которая логирует все HTTP хедеры, кроме авторизационных.

CHYT 2.17
Войдите, чтобы сохранить пост