Этот запрос пытается запустить внеплановое слияние частей данных в таблицах. Обратите внимание, что мы, как правило, не рекомендуем использовать OPTIMIZE TABLE ... FINAL (см. документацию), поскольку он предназначен для задач администрирования, а не для повседневной эксплуатации.
OPTIMIZE не может устранить ошибку Too many parts.
Синтаксис
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 на неактивных репликах.
Если alter_sync установлена в 2 и некоторые реплики остаются неактивными дольше времени, заданного настройкой replication_wait_for_inactive_replica_timeout, будет сгенерировано исключение UNFINISHED.
Оператор 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');
-- Симуляция слияния двух частей
OPTIMIZE TABLE dry_run_example DRY RUN PARTS 'all_1_1_0', 'all_2_2_0';
-- Симуляция слияния с дедупликацией
OPTIMIZE TABLE dry_run_example DRY RUN PARTS 'all_1_1_0', 'all_2_2_0' DEDUPLICATE;
-- Части и данные остаются неизменными после 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 │
└─────────────┴──────┘
Если вы хотите выполнять дедупликацию по произвольному набору столбцов, а не по всем сразу, можно явно указать список столбцов или использовать любую комбинацию выражений *, COLUMNS и EXCEPT. Явно указанный или неявно развёрнутый список столбцов должен включать все столбцы, указанные в выражении упорядочивания строк (и основной ключ, и ключ сортировки), а также в выражении партиционирования (ключ партиционирования).
Обратите внимание, что * ведёт себя так же, как в SELECT: столбцы MATERIALIZED и ALIAS не используются при развёртывании.Кроме того, указание пустого списка столбцов, запись выражения, которое приводит к пустому списку столбцов, или выполнение дедупликации по столбцу ALIAS считается ошибкой.
Синтаксис
OPTIMIZE TABLE table DEDUPLICATE; -- все столбцы
OPTIMIZE TABLE table DEDUPLICATE BY *; -- исключает столбцы MATERIALIZED и ALIAS
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);
┌─primary_key─┬─secondary_key─┬─value─┬─partition_key─┐
│ 0 │ 0 │ 0 │ 0 │
│ 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 │
│ 1 │ 1 │ 3 │ 3 │
└─────────────┴───────────────┴───────┴───────────────┘
Все приведенные ниже примеры выполняются для этого состояния, содержащего 5 строк.
Если столбцы для дедупликации не указаны, учитываются все столбцы. Строка удаляется только в том случае, если все значения во всех столбцах совпадают с соответствующими значениями в предыдущей строке:
OPTIMIZE TABLE example FINAL DEDUPLICATE;
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
Если столбцы указаны неявно, дедупликация таблицы выполняется по всем столбцам, кроме ALIAS и MATERIALIZED. Для приведённой выше таблицы это столбцы primary_key, secondary_key, value и partition_key:
OPTIMIZE TABLE example FINAL DEDUPLICATE BY *;
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
Выполняйте дедупликацию по всем столбцам, кроме ALIAS и MATERIALIZED, а также явно исключая value: столбцы primary_key, secondary_key и partition_key.
OPTIMIZE TABLE example FINAL DEDUPLICATE BY * EXCEPT value;
┌─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;
┌─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');
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
Последнее изменение 10 июня 2026 г.