Перейти к основному содержимому
Перейти к основному содержимому

Легковесное DELETE выражение

Легковесное 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 может потребовать значительных ресурсов, так как оно воссоздает все затронутые части.

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

Удаления большого объема могут негативно сказаться на производительности ClickHouse. Если вы пытаетесь удалить все строки из таблицы, рассмотрите возможность использования команды TRUNCATE TABLE.

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

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

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

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

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

Удаление больших объемов данных с помощью легковесного DELETE может отрицательно повлиять на производительность запросов SELECT.

Следующее также может негативно сказаться на производительности легковесного DELETE:

  • Тяжелое условие WHERE в запросе DELETE.
  • Если очередь мутаций заполнена многими другими мутациями, это может привести к проблемам с производительностью, так как все мутации в таблице выполняются последовательно.
  • Затронутая таблица имеет очень большое количество частей данных.
  • Наличие большого объема данных в компактных частях. В компактной части все столбцы хранятся в одном файле.

Права на удаление

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

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

  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 трансформируются в запросы ALTER TABLE ... 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, так как оно не переписывает все файлы столбцов для затронутых частей.