Обновление и удаление строк
Концептуально ADQM не предназначен для обновления и удаления данных, однако поддерживает возможность выполнения мутаций — операций изменения/удаления данных ALTER TABLE … UPDATE/DELETE
. Область применения мутаций — изменения, затрагивающие большое количество строк в таблице. Эти операции являются тяжеловесными и не подходят для частого использования (по возможности их лучше избегать).
Обновление данных
Обновить данные в таблице можно с помощью запроса ALTER TABLE…UPDATE
:
ALTER TABLE [<db_name>.]<table_name> [ON CLUSTER <cluster_name>] UPDATE <column_name> = <expression>[, ...] [IN PARTITION <partition_expr>] WHERE <filter_expression>;
В этом запросе:
-
[<db_name>.]<table_name>
— имя таблицы, в которой будут обновляться данные. Если имя базы данных не указано, таблица ищется в текущей базе данных. -
[ON CLUSTER <cluster_name>]
— имя кластера, на всех серверах которого будет выполняться запрос. Если выражениеON CLUSTER
не используется, запрос на обновление данных в таблице выполняется только на одном сервере. -
<column_name> = <expression>
— команда обновления значений в столбце. Значения столбца<column_name>
заменяются на вычисленное значение выражения<expression>
в каждой строке, для которой выражение<filter_expression>
возвращает ненулевое значение.
Значение выражения<expression>
должно быть того же типа данных, что и столбец<column_name>
, или должно быть приведено к тому же типу с помощью оператораCAST
.Один запрос может содержать несколько команд
<column_name> = <expression>
, разделенных запятыми. Изменение значений нескольких столбцов одним запросом может быть более эффективным, чем выполнение нескольких запросов, каждый из которых обновляет один столбец.Изменение столбцов, которые используются при вычислении первичного ключа или ключа сортировки, не поддерживается.
-
[IN PARTITION <partition_expr>]
— партиция, в которой будут обновляться данные. Использование выраженияIN PARTITION
помогает ускорить выполнение операцииUPDATE
, когда нужно точечно обновить данные в таблице, которая разбита на множество партиций. -
<filter_expression>
— выражение, возвращающее значение типа UInt8 для каждой строки таблицы, по которому будет определяться, в каких строках нужно обновить данные.
Исходная таблица:
--a---b----c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 2 │ b │ 20 │ 2022-12-11 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ e │ 50 │ 2022-12-14 │ │ 6 │ f │ 60 │ 2022-12-15 │ ---------------------------
Cледующий запрос заменяет значения столбцов b
и c
в строках, в которых значение столбца date
отвечает заданному условию:
ALTER TABLE test_table UPDATE b = repeat(b, 3), c = c/10 WHERE date > '2022-12-13';
Результат выполнения запроса обновления данных:
--a---b------c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 2 │ b │ 20 │ 2022-12-11 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ eee │ 5 │ 2022-12-14 │ │ 6 │ fff │ 6 │ 2022-12-15 │ -----------------------------
Для реплицируемых таблиц запросы ALTER TABLE…UPDATE
выполняются асинхронно. При необходимости синхронизировать обновление данных на репликах можно с помощью настройки mutations_sync.
Удаление данных
Для удаления строк данных из таблицы по заданному условию могут использоваться следующие запросы:
-
ALTER TABLE…DELETE
— поддерживается всеми движками таблиц. -
DELETE FROM
— поддерживается только движками таблиц семейства MergeTree (начиная с верcии ADQM 22.8).
В большинстве случаев запросы DELETE FROM
выполняются значительно быстрее, чем ALTER TABLE…DELETE
(эта операция требует слияния данных перед их удалением). DELETE FROM
считается легковесной операцией, которая эффективна для удаления небольшого количества строк. Для некоторых сценариев (например, для нечастого выполнения массового удаления данных) лучше подходит ALTER TABLE…DELETE
.
ALTER TABLE…DELETE
Синтаксис запроса:
ALTER TABLE [<db_name>.]<table_name> [ON CLUSTER <cluster_name>] DELETE [IN PARTITION <partition_expr>] WHERE <filter_expression>;
Запрос удаляет из таблицы <table_name>
строки, для которых выражение <filter_expression>
возвращает ненулевое значение (типа UInt8). Чтобы удалить строки только из определенной партиции, необходимо указать нужную партицию с помощью выражения IN PARTITION
.
Исходная таблица:
--a---b------c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 2 │ b │ 20 │ 2022-12-11 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ eee │ 5 │ 2022-12-14 │ │ 6 │ fff │ 6 │ 2022-12-15 │ -----------------------------
Следующий запрос удаляет из таблицы test_table
строки, в которых значения столбцов date
и a
удовлетворяют заданным условиям:
ALTER TABLE test_table DELETE WHERE date < '2022-12-13' AND a = 2;
Результат выполнения запроса:
--a---b------c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ eee │ 5 │ 2022-12-14 │ │ 6 │ fff │ 6 │ 2022-12-15 │ -----------------------------
Для реплицируемых таблиц запросы ALTER TABLE…DELETE
выполняются асинхронно. Если необходимо синхронизировать операцию удаления на репликах, измените значение настройки mutations_sync.
DELETE FROM
Синтаксис запроса:
DELETE FROM [<db_name>.]<table_name> [WHERE <filter_expression>];
Запрос удаляет из таблицы <table_name>
строки, для которых выражение <filter_expression>
возвращает ненулевое значение (типа UInt8). Удаляемые строки сразу помечаются как удаленные и автоматически исключаются из всех последующих запросов. Удаление данных происходит асинхронно в фоновом режиме (синхронность выполнения запросов определяется параметром mutations_sync).
Чтобы использовать запрос DELETE FROM
, необходимо предварительно включить настройку allow_experimental_lightweight_delete
:
SET allow_experimental_lightweight_delete = true;
Исходная таблица:
--a---b-------c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ eee │ 5 │ 2022-12-14 │ │ 6 │ fff │ 6 │ 2022-12-15 │ │ 7 │ aabb │ 10 │ 2022-12-16 │ │ 8 │ bbaa │ 20 │ 2022-12-17 │ ------------------------------
Следующий запрос удаляет из таблицы test_table
строки, в которых значения в столбце b
содержат текст aa
:
DELETE FROM test_table WHERE b LIKE '%aa%';
Результат выполнения запроса:
--a---b------c---------date-- │ 1 │ a │ 10 │ 2022-12-10 │ │ 3 │ c │ 30 │ 2022-12-12 │ │ 4 │ d │ 40 │ 2022-12-13 │ │ 5 │ eee │ 5 │ 2022-12-14 │ │ 6 │ fff │ 6 │ 2022-12-15 │ -----------------------------