DELETE удаляет строки из таблицы [db.]table, которые соответствуют выражению expr. Он доступен только для таблиц семейства *MergeTree.
DELETE” в отличие от команды ALTER TABLE … DELETE, которая является тяжеловесной операцией.
Примеры
Легковесный DELETE не удаляет данные сразу
DELETE реализован как мутация: он помечает строки как удалённые, но не удаляет их физически сразу.
По умолчанию команды DELETE дожидаются завершения пометки строк как удалённых перед тем, как вернуть результат. Если данных много, это может занять продолжительное время. В качестве альтернативы можно запустить операцию асинхронно в фоновом режиме с помощью настройки lightweight_deletes_sync. Если она отключена, оператор DELETE вернётся сразу, но данные могут оставаться видимыми для запросов, пока не завершится фоновая мутация.
Мутация не удаляет физически строки, помеченные как удалённые: это произойдёт только во время следующего слияния. В результате в течение неопределённого времени данные могут фактически оставаться в хранилище и быть лишь помеченными как удалённые.
Если вам нужно гарантировать удаление данных из хранилища в предсказуемые сроки, рассмотрите возможность использования настройки таблицы min_age_to_force_merge_seconds. Либо можно использовать команду ALTER TABLE … DELETE. Обратите внимание, что удаление данных с помощью ALTER TABLE ... DELETE может потребовать значительных ресурсов, поскольку при этом пересоздаются все затронутые части.
Удаление больших объёмов данных
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
-
К затронутым строкам применяется “маска”
Когда выполняется запрос
DELETE FROM table ..., ClickHouse сохраняет маску, в которой каждая строка помечается как “существующая” или “удалённая”. Эти “удалённые” строки исключаются из последующих запросов. Однако физически строки удаляются только позже, в ходе последующих слияний. Запись этой маски значительно менее затратна, чем выполнение запросаALTER TABLE ... DELETE. Маска реализована в виде скрытого системного столбца_row_exists, который хранитTrueдля всех видимых строк иFalseдля удалённых. Этот столбец присутствует в части только в том случае, если из неё были удалены некоторые строки. Если в части все значения равныTrue, этого столбца нет. -
Запросы
SELECTпреобразуются так, чтобы учитывать маску Когда в запросе используется столбец с маской, запросSELECT ... FROM table WHERE conditionвнутри ClickHouse дополняется предикатом по_row_existsи преобразуется в:Во время выполнения столбец_row_existsсчитывается, чтобы определить, какие строки не нужно возвращать. Если удалённых строк много, ClickHouse может определить, какие гранулы можно полностью пропустить при чтении остальных столбцов. -
Запросы
DELETEпреобразуются в запросыALTER TABLE ... UPDATEDELETE FROM table WHERE conditionпреобразуется в мутациюALTER TABLE table UPDATE _row_exists = 0 WHERE condition. Внутри ClickHouse эта мутация выполняется в два шага:-
Для каждой отдельной части выполняется команда
SELECT count() FROM table WHERE condition, чтобы определить, затронута ли эта часть. -
На основе результатов этих команд затем мутируются затронутые части, а для незатронутых создаются жёсткие ссылки. В случае широких частей столбец
_row_existsобновляется для каждой строки, а файлы всех остальных столбцов связываются жёсткими ссылками. Для компактных частей все столбцы перезаписываются, поскольку они хранятся вместе в одном файле.
DELETE, использующий технику маскирования, работает быстрее традиционногоALTER TABLE ... DELETE, потому что не требует перезаписывать файлы всех столбцов для затронутых частей. -
Для каждой отдельной части выполняется команда