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