INSERT
Описание
Этот оператор предназначен для вставки данных.
INSERT INTO table_name
[ PARTITION (p1, ...) ]
[ WITH LABEL label]
[ (column [, ...]) ]
[ [ hint [, ...] ] ]
{ VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
Параметры
tablet_name: Целевая таблица для загрузки данных. Можно указать в формате
db_name.table_namepartitions: Указывает разделы для загрузки данных. Эти разделы должны существовать в
table_name. Имена нескольких разделов разделяются запятымиlabel: Указывает метку для задачи Insert
column_name: Указывает целевой столбец. Этот столбец должен существовать в
table_nameexpression: Выражение, значение которого нужно присвоить столбцу
DEFAULT: Позволяет использовать значение по умолчанию для соответствующего столбца
query: Обычный запрос, результат которого будет записан в целевую таблицу
hint: Подсказка, определяющая поведение при выполнении
INSERT. Можно выбрать одно из следующих значений:/*+ STREAMING */,/*+ SHUFFLE */или `/*+ NOSHUFFLE */.
- STREAMING: В настоящее время не оказывает практического воздействия и сохранена только для совместимости с предыдущими версиями. (В предыдущей версии добавление этой подсказки приводило к возврату метки, а теперь метка возвращается по умолчанию)
- SHUFFLE: Если целевая таблица разделена на разделы, включение этой подсказки приведет к перераспределению данных между разделами.
- NOSHUFFLE: Даже если целевая таблица разделена на разделы, перераспределение данных между ними не выполняется. Вместо этого выполняются другие операции, обеспечивающие корректное размещение данных в каждом разделе.
Для таблицы Unique с включенным merge-on-write оператор insert также позволяет обновлять отдельные столбцы. Для этого необходимо установить переменную сеанса enable_unique_key_partial_update в true (по умолчанию эта переменная имеет значение false, то есть обновление отдельных столбцов с помощью оператора insert по умолчанию запрещено). При обновлении отдельных столбцов в список вставляемых столбцов необходимо включить как минимум все столбцы Key и указать столбцы, которые требуется обновить. Если значения столбцов Key вставляемой строки уже существуют в исходной таблице, данные строки с такими же значениями ключевых столбцов будут обновлены. Если значения столбцов Key вставляемой строки отсутствуют в исходной таблице, в таблицу будет добавлена новая строка. В этом случае столбцы, не указанные в операторе insert, должны либо иметь значения по умолчанию, либо допускать null. Сначала для этих отсутствующих столбцов предпринимается попытка использовать значения по умолчанию. Если у столбца нет значения по умолчанию, он заполняется значением null. Если столбец не допускает null, операция вставки завершится ошибкой.
Обратите внимание: переменная сеанса enable_insert_strict, определяющая, работает ли оператор insert в строгом режиме, по умолчанию имеет значение true. Другими словами, оператор insert по умолчанию работает в строгом режиме, в котором при обновлении отдельных столбцов запрещено обновлять несуществующие ключи. Поэтому, если при обновлении отдельных столбцов с помощью оператора insert требуется вставлять строки с несуществующими ключами, необходимо установить enable_unique_key_partial_update в true и одновременно установить enable_insert_strict в false.
Примечание:
При выполнении оператора INSERT по умолчанию отфильтровываются данные, не соответствующие формату целевой таблицы, например слишком длинные строки. Однако в бизнес-сценариях, где отфильтровывание данных недопустимо, можно установить переменную сеанса enable_insert_strict в true, чтобы INSERT не завершался успешно, если какие-либо данные были отфильтрованы.
Пример
Таблица test содержит два столбца: c1, c2.
- Загрузка одной строки данных в таблицу
test
INSERT INTO test VALUES (1, 2);
INSERT INTO test (c1, c2) VALUES (1, 2);
INSERT INTO test (c1, c2) VALUES (1, DEFAULT);
INSERT INTO test (c1) VALUES (1);
Первый и второй операторы дают одинаковый результат. Если целевые столбцы не указаны, по умолчанию используется порядок столбцов в таблице.
Третий и четвертый операторы также дают одинаковый результат: для загрузки данных используется значение по умолчанию столбца c2.
- Загрузка нескольких строк данных в таблицу
testза один раз
INSERT INTO test VALUES (1, 2), (3, 2 + 2);
INSERT INTO test (c1, c2) VALUES (1, 2), (3, 2 * 2);
INSERT INTO test (c1) VALUES (1), (3);
INSERT INTO test (c1, c2) VALUES (1, DEFAULT), (3, DEFAULT);
Первый и второй операторы дают одинаковый результат: загружают две строки данных в таблицу test за один раз.
Третий и четвертый операторы также дают одинаковый результат: значение по умолчанию столбца c2 используется для загрузки двух строк данных в таблицу test.
- Загрузка результата запроса в таблицу
test
INSERT INTO test SELECT * FROM test2;
INSERT INTO test (c1, c2) SELECT * from test2;
- Загрузка результата запроса в таблицу
testс указанием раздела и метки
INSERT INTO test PARTITION(p1, p2) WITH LABEL `label1` SELECT * FROM test2;
INSERT INTO test WITH LABEL `label1` (c1, c2) SELECT * from test2;
Ключевые слова
INSERT
Рекомендации
-
Просмотр возвращаемых результатов
Операция INSERT выполняется синхронно, и возврат результата означает завершение операции. Пользователю необходимо обработать результат в зависимости от его содержимого.
-
Выполнение успешно, набор результатов пуст
Если набор результатов оператора select, используемого в insert, пуст, возвращается следующий результат:
mysql> insert into tbl1 select * from empty_tbl;
Query OK, 0 rows affected (0.02 sec)Query OKуказывает на успешное выполнение.0 rows affectedозначает, что данные не были загружены. -
Выполнение успешно, набор результатов не пуст
Если набор результатов не пуст, возможны следующие варианты возвращаемых результатов:
-
Операция Insert выполнена успешно, данные видимы:
mysql> insert into tbl1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'insert_8510c568-9eda-4173-9e36-6adc7d35291c', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 with label my_label1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}Query OKуказывает на успешное выполнение.4 rows affectedозначает, что всего было загружено 4 строки данных.2 warningsуказывает количество отфильтровываемых строк.Также возвращается строка JSON:
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}
{'label':'my_label1', 'status':'visible', 'txnId':'4005', 'err':'some other error'}labelпредставляет собой метку, заданную пользователем или сгенерированную автоматически. Метка служит идентификатором этой задачи загрузки Insert Into. Каждая задача загрузки имеет уникальную метку в пределах одной базы данных.statusуказывает, видимы ли загруженные данные. Если данные видимы, отображаетсяvisible, если нет, отображаетсяcommitted.txnIdпредставляет собой идентификатор транзакции загрузки, соответствующей этой операции insert.Поле
errсодержит сведения о других непредвиденных ошибках.Для просмотра отфильтрованных строк можно выполнить следующий оператор:
show load where label="xxx";URL в возвращаемом результате позволяет просмотреть ошибочные данные. Подробнее см. в описании просмотра ошибочных строк ниже.
Невидимость данных является временным состоянием: в конечном итоге эта порция данных станет видимой
Проверить видимость этой порции данных можно с помощью следующего оператора:
show transaction where id=4005;Если столбец
TransactionStatusв возвращаемом результате имеет значениеvisible, данные видимы.
-
-
Выполнение завершилось ошибкой
Ошибка выполнения означает, что данные не были успешно загружены. Возвращается следующий результат:
mysql> insert into tbl1 select * from tbl2 where k1 = "a";
ERROR 1064 (HY000): all partitions have no load data. url: http://10.74.167.16:8042/api/_load_error_log?file=__shard_2/error_log_insert_stmt_ba8bb9e158e4879-ae8de8507c0bf8a2_ba8bb9e158e4879_ae8de8507c0Здесь
ERROR 1064 (HY000): all partitions have no load dataуказывает причину ошибки. Следующий за ним URL можно использовать для просмотра ошибочных данных:show load warnings on "url";Так можно просмотреть конкретную строку с ошибкой.
-
-
Время ожидания
Время ожидания операции INSERT определяется значением max(insert_timeout, query_timeout). Обе величины являются переменными окружения: insert_timeout по умолчанию составляет 4 часа, а query_timeout составляет 5 минут. Если операция превышает время ожидания, задача отменяется. Переменная insert_timeout введена для того, чтобы у операторов INSERT было большее время ожидания по умолчанию и задачи загрузки не зависели от более короткого времени ожидания, обычно применяемого к обычным запросам.
-
Метки и атомарность
Операция INSERT также гарантирует атомарность загрузки. См. документацию Транзакции загрузки и атомарность.
При использовании
CTE(Common Table Expressions)в качестве запроса в операции insert необходимо указать частиWITH LABELиcolumn. -
Порог фильтрации
В отличие от других способов загрузки, операции INSERT не позволяют задать порог фильтрации (
max_filter_ratio). По умолчанию порог фильтрации равен 1, что означает, что строки с ошибками можно игнорировать.В бизнес-сценариях, где отфильтровывание данных недопустимо, можно установить переменную сеанса
enable_insert_strictвtrue, чтобыINSERTне завершался успешно, если какие-либо данные были отфильтрованы. -
Вопросы производительности
Не вставляйте по одной строке с помощью метода
VALUES. Если необходимо использовать этот способ, объединяйте несколько строк данных в один оператор INSERT для пакетной фиксации.