У меня есть алгоритм, в котором мне нужно объединить две таблицы: первая таблица имеет 40 миллионов строк, а вторая - 300 000. Обе таблицы были созданы с одинаковым ORDER BY, поэтому при объединении я использую SETTINGS join_algorithm = 'full_sorting_merge', max_bytes_before_external_sort = 0; Это выглядит следующим образом:
SELECT A.* , B.* FROM db1.table1 A -- 40 millions of rows
left join (select * from db1.table2) B -- 300 000 rows
on A.col1 = B.col1
SETTINGS join_algorithm = 'full_sorting_merge', max_bytes_before_external_sort = 0;
Теперь мне нужно добавить дополнительную таблицу db1.table3 для объединения с db1.table1.
SELECT A.* , B.* FROM db1.table1 A -- 40 millions of rows
left join (select * from db1.table2) B -- 300 000 rows
on A.col1 = B.col1
left join (select * from db1.table3) C -- 400 000 rows
on A.col1 = C.col1
Где мне указать настройки алгоритма соединения? После каждого подключения? Или только в конце запроса? Если я укажу только один НАСТРОЙКИ в конце запроса, будет ли он распространяться на оба соединения? Есть ли возможность указать разные алгоритмы для каждого соединения в запросе? Пожалуйста, помогите
Для каждого запроса можно указать только одно предложение SETTINGS
, поэтому, если у вас есть несколько объединений в запросе, одни и те же настройки будут распространяться на оба. Это означает, что в настоящее время невозможно указать разные алгоритмы соединения для одного запроса.
Если вы хотите использовать разные настройки для каждого объединения, вам потребуется выполнить отдельные запросы с настройками для каждого соединения.
для 300 тысяч строк в правой таблице вы можете использовать engine=Join
и joinGet
смотреть
https://clickhouse.com/docs/en/engines/table-engines/special/join
и
https://clickhouse.com/docs/en/sql-reference/functions/other-functions#joinget
Этот способ приемлем для меня:
select
D*,C.* from
(select * from db1.table1 A left join db1.table2 B on A.col1 = B.col1 Settings
SETTINGS join_algorithm = 'full_sorting_merge', max_bytes_before_external_sort = 0;
) D
left join
db1.table3 C
ON D.col1 = C.col1
Основная цель заключалась в том, чтобы не нарушить быструю загрузку результата соединения таблиц A и B при добавлении новой таблицы C, именно об этом я и упоминал.
Перед добавлением таблицы C я использовал join_algorithm = 'full_sorting_merge' между таблицами A и B, поскольку это значительно сокращало время выполнения выбора, и у меня была возможность указать ORDER BY при создании таблиц A и B, чтобы отсортировать их в одном и том же порядке. Когда я попытался использовать «full_sorting_merge» внутри одной операции, например SELECT * from A join B join C Settings join_algorithm = 'full_sorting_merge'
, у меня возникла проблема с памятью (которой у меня не было, когда я только что присоединился к таблицам A и B). Используя указанный мной способ, у меня не возникает проблем с памятью (выполнен запрос более 10 раз и получено одинаковое время выполнения)
и время выполнения этого способа немного больше, чем исходный запрос, в котором я присоединился к таблицам A и B.
Просто хочу немного изменить количество строк, о которых я упомянул.
Table A 43 683 753
Table B 334 194
Table C 794
Я знаю, что лучше понять внутренности Clickhouse более глубоко, чтобы полностью понять природу проблемы и потребление памяти, но просто для быстрого решения, возможно, это будет кому-то полезно.
Настройки уровня запроса clickhouse.com/docs/en/operations/settings/query-level
AFAIK, вы можете добавить несколько алгоритмов join_algorithms, например
join_algorithm = 'hash,direct'
, но только 1 будет выбран в зависимости от типа/строгости и механизма таблицы.