Этот запрос пытается запустить внеплановое слияние частей данных в таблицах. Обратите внимание, что мы, как правило, не рекомендуем использовать OPTIMIZE TABLE ... FINAL (см. документацию), поскольку он предназначен для задач администрирования, а не для повседневной эксплуатации.
Синтаксис
OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL | FORCE] [DEDUPLICATE [BY expression]]OPTIMIZE TABLE [db.]name DRY RUN PARTS 'part_name1', 'part_name2' [, ...] [DEDUPLICATE [BY expression]] [CLEANUP]Запрос OPTIMIZE поддерживается для семейства MergeTree (включая materialized views) и движка Buffer. Другие движки таблиц не поддерживаются.
При использовании OPTIMIZE с семейством Движков таблиц ReplicatedMergeTree ClickHouse создаёт задачу на слияние и ждёт её выполнения на всех репликах (если настройка alter_sync установлена в 2) или на текущей реплике (если настройка alter_sync установлена в 1).
- Если
OPTIMIZEпо какой-либо причине не выполняет слияние, клиент не получает уведомление. Чтобы включить уведомления, используйте настройку optimize_throw_if_noop. - Если указать
PARTITION, будет оптимизирована только указанная партиция. Как задать выражение партиционирования. - Если указать
FINALилиFORCE, оптимизация выполняется, даже если все данные уже находятся в одной части. Управлять этим поведением можно с помощью optimize_skip_merged_partitions. Кроме того, слияние будет принудительно выполнено, даже если уже идут параллельные слияния. - Если указать
DEDUPLICATE, будут дедуплицированы полностью идентичные строки (если не указано предложение BY) — сравниваются все столбцы. Это имеет смысл только для движка MergeTree.
С помощью настройки replication_wait_for_inactive_replica_timeout можно указать, как долго (в секундах) ждать выполнения запросов OPTIMIZE на неактивных репликах.
DRY RUN
Оператор DRY RUN имитирует слияние указанных частей без фиксации результата. Слитая часть записывается во временное место, проверяется, а затем отбрасывается. Исходные части и данные таблицы остаются без изменений.
Это полезно для:
- Проверки корректности слияния в разных версиях ClickHouse.
- Детерминированного воспроизведения ошибок, связанных со слиянием.
- Бенчмаркинга производительности слияния.
DRY RUN поддерживается только для таблиц семейства MergeTree. Обязательно ключевое слово PARTS со списком имён частей. Все указанные части должны существовать, быть активными и принадлежать одной партиции.
DRY RUN несовместим с FINAL и PARTITION. Его можно использовать вместе с DEDUPLICATE (с необязательным указанием столбцов) и CLEANUP (для таблиц ReplacingMergeTree).
Синтаксис
OPTIMIZE TABLE [db.]name DRY RUN PARTS 'part_name1', 'part_name2' [, ...] [DEDUPLICATE [BY expression]] [CLEANUP]По умолчанию результирующая слитая часть проверяется аналогично запросу CHECK TABLE. Это поведение управляется настройкой optimize_dry_run_check_part (по умолчанию включена). Если отключить её, проверка будет пропущена, что может быть полезно для бенчмарка самого слияния.
Пример
CREATE TABLE dry_run_example (key UInt64, value String) ENGINE = MergeTree ORDER BY key;
INSERT INTO dry_run_example VALUES (1, 'a'), (2, 'b');
INSERT INTO dry_run_example VALUES (1, 'c'), (4, 'd');
-- Simulate merging using two parts
OPTIMIZE TABLE dry_run_example DRY RUN PARTS 'all_1_1_0', 'all_2_2_0';
-- Simulate merging with deduplication
OPTIMIZE TABLE dry_run_example DRY RUN PARTS 'all_1_1_0', 'all_2_2_0' DEDUPLICATE;
-- Parts and data remain unchanged after DRY RUN
SELECT name, rows FROM system.parts
WHERE database = currentDatabase() AND table = 'dry_run_example' AND active
ORDER BY name;┌─name────────┬─rows─┐
│ all_1_1_0 │ 2 │
│ all_2_2_0 │ 2 │
└─────────────┴──────┘Выражение BY
Если вы хотите выполнять дедупликацию по произвольному набору столбцов, а не по всем сразу, можно явно указать список столбцов или использовать любую комбинацию выражений *, COLUMNS и EXCEPT. Явно указанный или неявно развёрнутый список столбцов должен включать все столбцы, указанные в выражении упорядочивания строк (и основной ключ, и ключ сортировки), а также в выражении партиционирования (ключ партиционирования).
Синтаксис
OPTIMIZE TABLE table DEDUPLICATE; -- all columns
OPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns
OPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ;
OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;
OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);
OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');
OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;
OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);Примеры
Рассмотрим таблицу:
CREATE TABLE example (
primary_key Int32,
secondary_key Int32,
value UInt32,
partition_key UInt32,
materialized_value UInt32 MATERIALIZED 12345,
aliased_value UInt32 ALIAS 2,
PRIMARY KEY primary_key
) ENGINE=MergeTree
PARTITION BY partition_key
ORDER BY (primary_key, secondary_key);INSERT INTO example (primary_key, secondary_key, value, partition_key)
VALUES (0, 0, 0, 0), (0, 0, 0, 0), (1, 1, 2, 2), (1, 1, 2, 3), (1, 1, 3, 3);SELECT * FROM example;
┌Все приведенные ниже примеры выполняются для этого состояния, содержащего 5 строк.
DEDUPLICATE
Если столбцы для дедупликации не указаны, учитываются все столбцы. Строка удаляется только в том случае, если все значения во всех столбцах совпадают с соответствующими значениями в предыдущей строке:
OPTIMIZE TABLE example FINAL DEDUPLICATE;SELECT * FROM example;┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 2 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 3 │
│ 1 │ 1 │ 3 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘DEDUPLICATE BY *
Если столбцы указаны неявно, дедупликация таблицы выполняется по всем столбцам, кроме ALIAS и MATERIALIZED. Для приведённой выше таблицы это столбцы primary_key, secondary_key, value и partition_key:
OPTIMIZE TABLE example FINAL DEDUPLICATE BY *;SELECT * FROM example;┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 2 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 3 │
│ 1 │ 1 │ 3 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘DEDUPLICATE BY * EXCEPT
Выполняйте дедупликацию по всем столбцам, кроме ALIAS и MATERIALIZED, а также явно исключая value: столбцы primary_key, secondary_key и partition_key.
OPTIMIZE TABLE example FINAL DEDUPLICATE BY * EXCEPT value;SELECT * FROM example;┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 2 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘DEDUPLICATE BY <list of columns>
Явно выполните дедупликацию по столбцам primary_key, secondary_key и partition_key:
OPTIMIZE TABLE example FINAL DEDUPLICATE BY primary_key, secondary_key, partition_key;SELECT * FROM example;┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 2 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘DEDUPLICATE BY COLUMNS(<regex>)
Выполнять дедупликацию по всем столбцам, соответствующим регулярному выражению: primary_key, secondary_key и partition_key:
OPTIMIZE TABLE example FINAL DEDUPLICATE BY COLUMNS('.*_key');SELECT * FROM example;┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 2 │
└─────────────┴───────────────┴───────┴───────────────┘
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 1 │ 1 │ 2 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘