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

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

Между этими версиями целый год изменений, вот некоторые функциональные улучшения, которые нам кажутся интересными для иллюстрации.
Рекурсивные 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 хедеры, кроме авторизационных.
Из основных изменений:
- Обновление версии ClickHouse с 23.8 до 24.8
- Добавили функцию ConvertYsonToJson
- Поддержка explain
- Поддержка многопоточного INSERT*
- Сборка HTTP‑header’ов в query_log
* в несортированные статически таблицы