INSERT OVERWRITE
Описание
Этот оператор позволяет перезаписать таблицу или отдельные её партиции
INSERT OVERWRITE table table_name
[ PARTITION (p1, ... | *) ]
[ WITH LABEL label]
[ (column [, ...]) ]
[ [ hint [, ...] ] ]
{ VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
Параметры
table_name: целевая таблица для перезаписи. Эта таблица должна существовать. Её имя можно указать в формате
db_name.table_namepartitions: партиции таблицы, которые нужно перезаписать. Поддерживаются следующие два формата
- Имена партиций. Указываются имена существующих партиций таблицы
table_name, разделённые запятыми- Звёздочка (*). Включает автоматическое определение партиций. Операция записи автоматически определяет партиции, к которым относятся данные, и перезаписывает их. Этот формат поддерживается начиная с версии Apache Doris 2.1.3.
label: метка для задачи Insert
column_name: указанный целевой столбец должен быть одним из существующих столбцов таблицы
table_nameexpression: выражение, значение которого нужно присвоить столбцу
DEFAULT: использовать для столбца значение по умолчанию
query: обычный запрос, результат которого перезапишет целевые данные.
hint: подсказка, определяющая поведение оператора
INSERTпри выполнении. Можно выбрать одно из следующих значений:/*+ STREAMING */,/*+ SHUFFLE */или/*+ NOSHUFFLE */.
- STREAMING: в настоящее время не влияет на выполнение и сохранён только для совместимости с предыдущими версиями. (В предыдущей версии добавление этой подсказки приводило к возврату метки, а теперь метка возвращается по умолчанию.)
- SHUFFLE: если целевая таблица партиционирована, включение этой подсказки приводит к перераспределению данных по партициям.
- NOSHUFFLE: даже если целевая таблица партиционирована, перераспределение данных по партициям не выполняется. Вместо этого выполняются другие операции, обеспечивающие корректное попадание данных в каждую партицию.
Примечание:
- В текущей версии переменная сеанса
enable_insert_strictпо умолчанию имеет значениеtrue. Если при выполнении оператораINSERT OVERWRITEотфильтровываются данные, не соответствующие формату целевой таблицы, например при перезаписи партиции, когда выполнены не все условия партиционирования, перезапись целевой таблицы завершится ошибкой. - Оператор
INSERT OVERWRITEсначала создаёт новую таблицу и вставляет в неё данные для перезаписи, а затем атомарно заменяет старую таблицу новой и переименовывает её. Поэтому во время перезаписи таблицы данные в старой таблице остаются доступны в обычном режиме до завершения операции.
Для таблиц с автоматическим партиционированием
Если целевая таблица оператора INSERT OVERWRITE использует автоматическое партиционирование, её поведение определяется переменной сеанса enable_auto_create_when_overwrite следующим образом:
- Если PARTITION не указан (перезапись всей таблицы), при значении
enable_auto_create_when_overwrite, равномtrue, таблица перезаписывается, а для данных без соответствующей партиции создаются партиции по правилам автоматического партиционирования таблицы, после чего эти данные записываются. Если значениеenable_auto_create_when_overwriteравноfalse, строки, для которых не найдена партиция, учитываются как ошибочные, пока операция не завершится ошибкой. - Если для перезаписи указан PARTITION, таблица AUTO PARTITION в ходе этой операции ведёт себя как обычная партиционированная таблица: данные, не удовлетворяющие условиям существующей партиции, отфильтровываются, а новая партиция не создаётся.
- Если PARTITION указан как
partition(*)(автоматическое определение и перезапись партиций), то при значенииenable_auto_create_when_overwrite, равномtrue, для данных, имеющих соответствующие партиции в таблице, перезаписываются эти партиции, а остальные существующие партиции остаются без изменений. При этом для данных без соответствующих партиций создаются партиции по правилам автоматического партиционирования таблицы, и эти данные записываются в них. Если значениеenable_auto_create_when_overwriteравноfalse, строки, для которых не найдена партиция, учитываются как ошибочные, пока операция не завершится ошибкой.
В версиях, в которых отсутствует enable_auto_create_when_overwrite, поведение соответствует значению false этой переменной.
Краткая сводка:
- Для таблиц с автоматическим партиционированием, в которых включена опция
enable_auto_create_when_overwrite:
| Перезаписываемые партиции | Очистка остальных партиций | Автоматическое создание партиций для данных без партиции | |
|---|---|---|---|
| Без указания партиций (вся таблица) | Все | √ | √ |
| Указанная партиция | Явно указанная партиция | × | × |
partition(*) | Партиция, к которой относятся данные | × | √ |
- Для обычных таблиц и таблиц с автоматическим партиционированием, в которых отключена опция
enable_auto_create_when_overwrite:
| Перезаписываемые партиции | Очистка остальных партиций | Автоматическое создание партиций для данных без партиции | |
|---|---|---|---|
| Без указания партиций (вся таблица) | Все | √ | × |
| Указанная партиция | Явно указанная партиция | × | × |
partition(*) | Партиция, к которой относятся данные | × | × |
Ниже приведены примеры:
mysql> create table auto_list(
-> k0 varchar null
-> )
-> auto partition by list (k0)
-> (
-> PARTITION p1 values in (("Beijing"), ("BEIJING")),
-> PARTITION p2 values in (("Shanghai"), ("SHANGHAI")),
-> PARTITION p3 values in (("xxx"), ("XXX")),
-> PARTITION p4 values in (("list"), ("LIST")),
-> PARTITION p5 values in (("1234567"), ("7654321"))
-> )
-> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
-> properties("replication_num" = "1");
Query OK, 0 rows affected (0.14 sec)
mysql> insert into auto_list values ("Beijing"),("Shanghai"),("xxx"),("list"),("1234567");
Query OK, 5 rows affected (0.22 sec)
mysql> insert overwrite table auto_list partition(*) values ("BEIJING"), ("new1");
Query OK, 2 rows affected (0.28 sec)
mysql> select * from auto_list;
+----------+ --- p1 is overwritten, new1 gets the new partition, and the other partitions remain unchanged.
| k0 |
+----------+
| 1234567 |
| BEIJING |
| list |
| xxx |
| new1 |
| Shanghai |
+----------+
6 rows in set (0.48 sec)
mysql> insert overwrite table auto_list values ("SHANGHAI"), ("new2");
Query OK, 2 rows affected (0.17 sec)
mysql> select * from auto_list;
+----------+ --- The whole table is overwritten, and new2 gets the new partition.
| k0 |
+----------+
| new2 |
| SHANGHAI |
+----------+
2 rows in set (0.15 sec)
Пример
Предположим, существует таблица test. В ней есть два столбца c1 и c2 и две партиции p1 и p2
CREATE TABLE IF NOT EXISTS test (
`c1` int NOT NULL DEFAULT "1",
`c2` int NOT NULL DEFAULT "4"
) ENGINE=OLAP
UNIQUE KEY(`c1`)
PARTITION BY LIST (`c1`)
(
PARTITION p1 VALUES IN ("1","2","3"),
PARTITION p2 VALUES IN ("4","5","6")
)
DISTRIBUTED BY HASH(`c1`) BUCKETS 3
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"in_memory" = "false",
"storage_format" = "V2"
);
Перезапись таблицы
-
Перезапись таблицы
testс помощьюVALUES.// Single-row overwrite.
INSERT OVERWRITE table test VALUES (1, 2);
INSERT OVERWRITE table test (c1, c2) VALUES (1, 2);
INSERT OVERWRITE table test (c1, c2) VALUES (1, DEFAULT);
INSERT OVERWRITE table test (c1) VALUES (1);
// Multi-row overwrite.
INSERT OVERWRITE table test VALUES (1, 2), (3, 2 + 2);
INSERT OVERWRITE table test (c1, c2) VALUES (1, 2), (3, 2 * 2);
INSERT OVERWRITE table test (c1, c2) VALUES (1, DEFAULT), (3, DEFAULT);
INSERT OVERWRITE table test (c1) VALUES (1), (3);
- Первый и второй операторы дают одинаковый результат. Если при перезаписи целевые столбцы не указаны, по умолчанию используется порядок столбцов в таблице. После успешной перезаписи в таблице
testостаётся только одна строка данных. - Третий и четвёртый операторы дают одинаковый результат. Неуказанный столбец
c2заполняется значением по умолчанию 4. После успешной перезаписи в таблицеtestостаётся только одна строка данных. - Пятый и шестой операторы дают одинаковый результат. В операторе можно использовать выражения (например,
2+2,2*2). Результат выражения вычисляется при выполнении оператора и записывается в таблицуtestс перезаписью её данных. После успешной перезаписи в таблицеtestостаются две строки данных. - Седьмой и восьмой операторы дают одинаковый результат. Неуказанный столбец
c2заполняется значением по умолчанию 4. После успешной перезаписи в таблицеtestостаются две строки данных.
-
Перезапись таблицы
testс помощью запроса. Формат данных в таблицеtest2должен совпадать с форматом данных в таблицеtest. Если форматы различаются, выполняется неявное преобразование типов данных.INSERT OVERWRITE table test SELECT * FROM test2;
INSERT OVERWRITE table test (c1, c2) SELECT * from test2;
- Первый и второй операторы дают одинаковый результат. Эти операторы берут данные из таблицы
test2и перезаписывают ими таблицуtest. После успешной перезаписи данные в таблицеtestсовпадают с данными в таблицеtest2.
-
Перезапись таблицы
testс указанием метки.INSERT OVERWRITE table test WITH LABEL `label1` SELECT * FROM test2;
INSERT OVERWRITE table test WITH LABEL `label2` (c1, c2) SELECT * from test2;
- С помощью команды
SHOW LOAD;можно проверить состояние задания загрузки с указанной меткойlabel. Метка должна быть уникальной.
Перезапись партиций таблицы
При перезаписи партиций с помощью INSERT OVERWRITE следующие три шага объединяются в одну транзакцию. Если в ходе выполнения произойдёт сбой, уже выполненные операции будут отменены:
- Если для перезаписи указана партиция
p1, сначала создаётся пустая временная партицияpTMPс такой же структурой, как у целевой партиции. - Данные записываются в
pTMP. - Партиция
p1атомарно заменяется партициейpTMP.
Ниже приведены примеры:
-
Перезапись партиций
P1иP2таблицыtestс помощьюVALUES.// Single-row overwrite.
INSERT OVERWRITE table test PARTITION(p1,p2) VALUES (1, 2);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1, c2) VALUES (1, 2);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1, c2) VALUES (1, DEFAULT);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1) VALUES (1);
// Multi-row overwrite.
INSERT OVERWRITE table test PARTITION(p1,p2) VALUES (1, 2), (4, 2 + 2);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1, c2) VALUES (1, 2), (4, 2 * 2);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1, c2) VALUES (1, DEFAULT), (4, DEFAULT);
INSERT OVERWRITE table test PARTITION(p1,p2) (c1) VALUES (1), (4);В отличие от перезаписи всей таблицы, эти операторы перезаписывают её партиции. Их можно перезаписывать по одной или по несколько за раз. Успешно записываются только данные, удовлетворяющие условию отбора соответствующей партиции. Если среди записываемых данных есть строки, не соответствующие ни одной из указанных партиций, перезапись завершится ошибкой. Ниже приведён пример такой ошибки.
INSERT OVERWRITE table test PARTITION(p1,p2) VALUES (7, 2);Данные, записываемые приведённым выше оператором (
c1=7), не удовлетворяют условиям партицийP1иP2, поэтому перезапись завершится ошибкой. -
Перезапись партиций
P1иP2таблицыtestс помощью запроса. Формат данных в таблицеtest2должен совпадать с форматом данных в таблицеtest. Если форматы различаются, выполняется неявное преобразование типов данных.INSERT OVERWRITE table test PARTITION(p1,p2) SELECT * FROM test2;
INSERT OVERWRITE table test PARTITION(p1,p2) (c1, c2) SELECT * from test2; -
Перезапись партиций
P1иP2таблицыtestс указанием метки.INSERT OVERWRITE table test PARTITION(p1,p2) WITH LABEL `label3` SELECT * FROM test2;
INSERT OVERWRITE table test PARTITION(p1,p2) WITH LABEL `label4` (c1, c2) SELECT * from test2;
Перезапись с автоматическим определением партиций
Эта возможность доступна начиная с версии 2.1.3.
Если в команде INSERT OVERWRITE условие PARTITION указано как PARTITION(*), операция перезаписи автоматически определяет партиции, к которым относятся данные. Пример:
mysql> create table test(
-> k0 int null
-> )
-> partition by range (k0)
-> (
-> PARTITION p10 values less than (10),
-> PARTITION p100 values less than (100),
-> PARTITION pMAX values less than (maxvalue)
-> )
-> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
-> properties("replication_num" = "1");
Query OK, 0 rows affected (0.11 sec)
mysql> insert into test values (1), (2), (15), (100), (200);
Query OK, 5 rows affected (0.29 sec)
mysql> select * from test order by k0;
+------+
| k0 |
+------+
| 1 |
| 2 |
| 15 |
| 100 |
| 200 |
+------+
5 rows in set (0.23 sec)
mysql> insert overwrite table test partition(*) values (3), (1234);
Query OK, 2 rows affected (0.24 sec)
mysql> select * from test order by k0;
+------+
| k0 |
+------+
| 3 |
| 15 |
| 1234 |
+------+
3 rows in set (0.20 sec)
Как видно из примера, все данные в партициях p10 и pMAX, к которым относятся значения 3 и 1234, перезаписываются, а партиция p100 остаётся без изменений. Эту операцию можно рассматривать как синтаксический сахар для явного указания перезаписываемой партиции в условии PARTITION при выполнении INSERT OVERWRITE. Она реализована так же, как перезапись указанной партиции. Синтаксис PARTITION(*) избавляет от необходимости вручную перечислять имена всех партиций при перезаписи большого количества партиций.
Ключевые слова
INSERT OVERWRITE, OVERWRITE, AUTO DETECT