Skip to main content
Оператор легковесного DELETE удаляет строки из таблицы [db.]table, соответствующие выражению expr. Он доступен только для таблиц семейства *MergeTree.
Это называется “легковесный DELETE”, чтобы отличать его от команды ALTER TABLE … DELETE, которая является ресурсоёмкой операцией.

Примеры

Легковесный DELETE не удаляет данные сразу

Легковесный DELETE помечает строки как удалённые, но не удаляет их из хранилища сразу. По умолчанию для этого используется мутация. В зависимости от настройки lightweight_delete_mode также могут использоваться патч-части. В режиме с мутациями, используемом по умолчанию, операторы DELETE дожидаются завершения пометки строк как удалённых, и только после этого возвращают результат. Это может занять много времени, если объём данных велик. В качестве альтернативы можно запустить удаление асинхронно в фоновом режиме с помощью настройки lightweight_deletes_sync. Если она отключена, оператор DELETE вернётся сразу, но данные могут по-прежнему быть видны в запросах, пока фоновая мутация не завершится. В обоих режимах удалённые строки остаются в хранилище до очистки. Обычно они удаляются из затронутых частей данных при фоновых слияниях. Чтобы явно применить маску удаления, используйте ALTER TABLE ... APPLY DELETED MASK. Эта команда выполняет ресурсоёмкую мутацию. Если вам нужно гарантировать удаление данных из хранилища в предсказуемые сроки, рассмотрите возможность использования настройки таблицы min_age_to_force_merge_seconds. Либо можно использовать команду ALTER TABLE … DELETE. Обратите внимание, что удаление данных с помощью ALTER TABLE ... DELETE может потребовать значительных ресурсов, так как при этом пересоздаются все затронутые части.

Выбор режима удаления

Настройка lightweight_delete_mode позволяет выбрать между удалением через мутации (по умолчанию) и легковесными обновлениями, при которых для удалённых строк записываются патч-части с _row_exists = 0. Запросы применяют эти патчи ещё до физической очистки данных. Доступные режимы описаны в справке по этой настройке, а предварительные условия — в разделе требования к легковесному обновлению. При использовании патч-частей lightweight_deletes_sync не дожидается остальных реплик; в ReplicatedMergeTree другие реплики могут возвращать удалённые строки, пока не получат патч.

Удаление больших объёмов данных

Удаление больших объёмов данных может отрицательно сказаться на производительности ClickHouse. Если вам нужно удалить из таблицы все строки, рассмотрите возможность использовать команду TRUNCATE TABLE. Если вы ожидаете частых удалений, рассмотрите возможность использовать пользовательский ключ партиционирования. В этом случае можно использовать команду ALTER TABLE ... DROP PARTITION, чтобы быстро удалить все строки, относящиеся к этой партиции.

Ограничения легковесного DELETE

Легковесные DELETE с проекциями

По умолчанию DELETE не работает с таблицами, содержащими проекции. Это связано с тем, что операция DELETE может затрагивать строки в проекции. Однако это поведение можно изменить с помощью настройки MergeTree lightweight_mutation_projection_mode.

Особенности производительности при использовании легковесного DELETE

Удаление больших объёмов данных с помощью легковесного оператора DELETE может негативно сказаться на производительности запросов SELECT. На производительность легковесного DELETE также могут негативно влиять следующие факторы:
  • Сложное условие WHERE в запросе DELETE.
  • При удалении с помощью мутаций — большая очередь мутаций: все мутации таблицы выполняются последовательно.
  • Затронутая таблица содержит очень большое число частей данных.
  • При удалении с помощью мутаций — большой объём данных в компактных частях. В компактной части все столбцы хранятся в одном файле, и их приходится перезаписывать вместе.

Разрешения для DELETE

Для выполнения DELETE требуется привилегия ALTER DELETE. Чтобы разрешить пользователю выполнять операторы DELETE для конкретной таблицы, выполните следующую команду:

Как в ClickHouse внутренне работает легковесный DELETE

  1. К затронутым строкам применяется «маска» Когда выполняется запрос DELETE FROM table ..., ClickHouse сохраняет маску, в которой каждая строка помечается как «существующая» или «удалённая». Такие «удалённые» строки исключаются из последующих запросов. Однако физически строки удаляются позже, как правило, во время фоновых слияний. Запись этой маски гораздо менее затратна, чем выполнение запроса ALTER TABLE ... DELETE. Маска реализована в виде скрытого системного столбца _row_exists, который хранит True для всех видимых строк и False для удалённых. Этот столбец присутствует в части только если в ней были удалены некоторые строки. Если в части все значения равны True, этот столбец отсутствует.
  2. Запросы SELECT преобразуются с учётом маски Когда в запросе используется замаскированный столбец, запрос SELECT ... FROM table WHERE condition внутренне дополняется предикатом по _row_exists и преобразуется в:
    Во время выполнения столбец _row_exists считывается, чтобы определить, какие строки не нужно возвращать. Если удалённых строк много, ClickHouse может определить, какие гранулы можно полностью пропустить при чтении остальных столбцов.
  3. Запросы DELETE обновляют маску в соответствии с выбранным режимом При использовании патч-частей DELETE FROM table WHERE condition преобразуется в UPDATE table SET _row_exists = 0 WHERE condition. Создаваемые при этом патч-части хранят изменения маски для удалённых строк и применяются при чтении и слиянии данных. В режиме alter_update, используемом по умолчанию, запрос DELETE FROM table WHERE condition преобразуется в мутацию ALTER TABLE table UPDATE _row_exists = 0 WHERE condition. Внутренне эта мутация выполняется в два шага:
    1. Для каждой отдельной части выполняется команда SELECT count() FROM table WHERE condition, чтобы определить, затронута ли эта часть.
    2. На основе результатов этих команд затем изменяются затронутые части, а для незатронутых создаются жёсткие ссылки. В случае широких частей столбец _row_exists обновляется для каждой строки, а файлы всех остальных столбцов связываются жёсткими ссылками. Для компактных частей все столбцы перезаписываются, потому что они хранятся вместе в одном файле.
    Из описанных выше шагов видно, что легковесный DELETE, использующий технику маскирования, работает быстрее традиционного ALTER TABLE ... DELETE, потому что не требует перезаписи файлов всех столбцов в затронутых частях.