> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8c05c8a2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Документация по OPTIMIZE

# Оператор OPTIMIZE

Этот запрос пытается запустить внеплановое слияние частей данных в таблицах. Обратите внимание, что мы, как правило, не рекомендуем использовать `OPTIMIZE TABLE ... FINAL` (см. [документацию](/ru/concepts/best-practices/avoid-optimize-final)), поскольку он предназначен для задач администрирования, а не для повседневной эксплуатации.

<Note>
  `OPTIMIZE` не может устранить ошибку `Too many parts`.
</Note>

**Синтаксис**

```sql theme={null}
OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL | FORCE] [DEDUPLICATE [BY expression]]
```

```sql theme={null}
OPTIMIZE TABLE [db.]name DRY RUN PARTS 'part_name1', 'part_name2' [, ...] [DEDUPLICATE [BY expression]] [CLEANUP]
```

Запрос `OPTIMIZE` поддерживается для семейства [MergeTree](/ru/reference/engines/table-engines/mergetree-family/mergetree) (включая [materialized views](/ru/reference/statements/create/view#materialized-view)) и движка [Buffer](/ru/reference/engines/table-engines/special/buffer). Другие движки таблиц не поддерживаются.

При использовании `OPTIMIZE` с семейством Движков таблиц [ReplicatedMergeTree](/ru/reference/engines/table-engines/mergetree-family/replication) ClickHouse создаёт задачу на слияние и ждёт её выполнения на всех репликах (если настройка [alter\_sync](/ru/reference/settings/session-settings#alter_sync) установлена в `2`) или на текущей реплике (если настройка [alter\_sync](/ru/reference/settings/session-settings#alter_sync) установлена в `1`).

* Если `OPTIMIZE` по какой-либо причине не выполняет слияние, клиент не получает уведомление. Чтобы включить уведомления, используйте настройку [optimize\_throw\_if\_noop](/ru/reference/settings/session-settings#optimize_throw_if_noop).
* Если указать `PARTITION`, будет оптимизирована только указанная партиция. [Как задать выражение партиционирования](/ru/reference/statements/alter/partition#how-to-set-partition-expression).
* Если указать `FINAL` или `FORCE`, оптимизация выполняется, даже если все данные уже находятся в одной части. Управлять этим поведением можно с помощью [optimize\_skip\_merged\_partitions](/ru/reference/settings/session-settings#optimize_skip_merged_partitions). Кроме того, слияние будет принудительно выполнено, даже если уже идут параллельные слияния.
* Если указать `DEDUPLICATE`, будут дедуплицированы полностью идентичные строки (если не указано предложение BY) — сравниваются все столбцы. Это имеет смысл только для движка MergeTree.

С помощью настройки [replication\_wait\_for\_inactive\_replica\_timeout](/ru/reference/settings/session-settings#replication_wait_for_inactive_replica_timeout) можно указать, как долго (в секундах) ждать выполнения запросов `OPTIMIZE` на неактивных репликах.

<Note>
  Если `alter_sync` установлена в `2` и некоторые реплики остаются неактивными дольше времени, заданного настройкой `replication_wait_for_inactive_replica_timeout`, будет сгенерировано исключение `UNFINISHED`.
</Note>

<div id="dry-run">
  ## DRY RUN
</div>

Оператор `DRY RUN` имитирует слияние указанных частей без фиксации результата. Слитая часть записывается во временное место, проверяется, а затем отбрасывается. Исходные части и данные таблицы остаются без изменений.

Это полезно для:

* Проверки корректности слияния в разных версиях ClickHouse.
* Детерминированного воспроизведения ошибок, связанных со слиянием.
* Бенчмаркинга производительности слияния.

`DRY RUN` поддерживается только для таблиц семейства [MergeTree](/ru/reference/engines/table-engines/mergetree-family/mergetree). Обязательно ключевое слово `PARTS` со списком имён частей. Все указанные части должны существовать, быть активными и принадлежать одной партиции.

`DRY RUN` несовместим с `FINAL` и `PARTITION`. Его можно использовать вместе с `DEDUPLICATE` (с необязательным указанием столбцов) и `CLEANUP` (для таблиц `ReplacingMergeTree`).

**Синтаксис**

```sql theme={null}
OPTIMIZE TABLE [db.]name DRY RUN PARTS 'part_name1', 'part_name2' [, ...] [DEDUPLICATE [BY expression]] [CLEANUP]
```

По умолчанию результирующая слитая часть проверяется аналогично запросу [`CHECK TABLE`](/ru/reference/statements/check-table). Это поведение управляется настройкой [optimize\_dry\_run\_check\_part](/ru/reference/settings/session-settings#optimize_dry_run_check_part) (по умолчанию включена). Если отключить её, проверка будет пропущена, что может быть полезно для бенчмарка самого слияния.

**Пример**

```sql theme={null}
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;
```

```response theme={null}
┌─name────────┬─rows─┐
│ all_1_1_0   │    2 │
│ all_2_2_0   │    2 │
└─────────────┴──────┘
```

<div id="by-expression">
  ## Выражение BY
</div>

Если вы хотите выполнять дедупликацию по произвольному набору столбцов, а не по всем сразу, можно явно указать список столбцов или использовать любую комбинацию выражений [`*`](/ru/reference/statements/select/index#asterisk), [`COLUMNS`](/ru/reference/statements/select/index#select-clause) и [`EXCEPT`](/ru/reference/statements/select/except_modifier). Явно указанный или неявно развёрнутый список столбцов должен включать все столбцы, указанные в выражении упорядочивания строк (и основной ключ, и ключ сортировки), а также в выражении партиционирования (ключ партиционирования).

<Note>
  Обратите внимание, что `*` ведёт себя так же, как в `SELECT`: столбцы [MATERIALIZED](/ru/reference/statements/create/view#materialized-view) и [ALIAS](/ru/reference/statements/create/table#alias) не используются при развёртывании.

  Кроме того, указание пустого списка столбцов, запись выражения, которое приводит к пустому списку столбцов, или выполнение дедупликации по столбцу `ALIAS` считается ошибкой.
</Note>

**Синтаксис**

```sql theme={null}
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);
```

**Примеры**

Рассмотрим таблицу:

```sql title="Query" theme={null}
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);
```

```sql title="Query" theme={null}
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);
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```sql title="Response" theme={null}

┌─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 строк.

<div id="deduplicate">
  #### `DEDUPLICATE`
</div>

Если столбцы для дедупликации не указаны, учитываются все столбцы. Строка удаляется только в том случае, если все значения во всех столбцах совпадают с соответствующими значениями в предыдущей строке:

```sql title="Query" theme={null}
OPTIMIZE TABLE example FINAL DEDUPLICATE;
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```response title="Response" theme={null}
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
```

<div id="deduplicate-by-">
  #### `DEDUPLICATE BY *`
</div>

Если столбцы указаны неявно, дедупликация таблицы выполняется по всем столбцам, кроме `ALIAS` и `MATERIALIZED`. Для приведённой выше таблицы это столбцы `primary_key`, `secondary_key`, `value` и `partition_key`:

```sql title="Query" theme={null}
OPTIMIZE TABLE example FINAL DEDUPLICATE BY *;
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```response title="Response" theme={null}
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
```

<div id="deduplicate-by--except">
  #### `DEDUPLICATE BY * EXCEPT`
</div>

Выполняйте дедупликацию по всем столбцам, кроме `ALIAS` и `MATERIALIZED`, а также явно исключая `value`: столбцы `primary_key`, `secondary_key` и `partition_key`.

```sql title="Query" theme={null}
OPTIMIZE TABLE example FINAL DEDUPLICATE BY * EXCEPT value;
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```response title="Response" theme={null}
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
```

<div id="deduplicate-by-list-of-columns">
  #### `DEDUPLICATE BY <list of columns>`
</div>

Явно выполните дедупликацию по столбцам `primary_key`, `secondary_key` и `partition_key`:

```sql title="Query" theme={null}
OPTIMIZE TABLE example FINAL DEDUPLICATE BY primary_key, secondary_key, partition_key;
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```response title="Response" theme={null}
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
```

<div id="deduplicate-by-columnsregex">
  #### `DEDUPLICATE BY COLUMNS(<regex>)`
</div>

Выполнить дедупликацию по всем столбцам, соответствующим регулярному выражению: `primary_key`, `secondary_key` и `partition_key`:

```sql title="Query" theme={null}
OPTIMIZE TABLE example FINAL DEDUPLICATE BY COLUMNS('.*_key');
```

```sql title="Query" theme={null}
SELECT * FROM example;
```

```response title="Response" theme={null}
┌─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 │
└─────────────┴───────────────┴───────┴───────────────┘
```
