INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
SELECT ...
[ON DUPLICATE KEY UPDATE assignment_list]
value:
{expr | DEFAULT}
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...
使用INSERT ...
SELECT
,您可以从一个语句的结果中快速地将许多行插入到一个表中,该SELECT
语句可以从一个或多个表中进行选择。例如:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
以下条件适用于
INSERT ...
SELECT
语句:
指定
IGNORE
忽略会导致重复键违规的行。DELAYED
被忽略INSERT ... SELECT
。语句的目标表
INSERT
可能出现在查询部分的FROM
子句中 。SELECT
但是,您不能在子查询中插入表并从同一个表中进行选择。当从同一个表中进行选择和插入时,MySQL 创建一个内部临时表来保存来自的行
SELECT
,然后将这些行插入到目标表中。但是,您不能使用INSERT INTO t ... SELECT ... FROM t
whent
is aTEMPORARY
table,因为TEMPORARY
不能在同一语句中引用两次表。请参阅 第 8.4.4 节,“MySQL 中的内部临时表使用”和 第 B.3.6.2 节,“临时表问题”。AUTO_INCREMENT
专栏照常工作。为确保二进制日志可用于重新创建原始表,MySQL 不允许对
INSERT ... SELECT
语句进行并发插入(请参阅 第 8.11.3 节,“并发插入”)。为避免在
SELECT
和INSERT
引用同一个表时出现不明确的列引用问题,请为该部分中使用的每个表提供唯一的别名SELECT
,并使用适当的别名限定该部分中的列名。
您可以明确选择源表或目标表(或两者)的哪些分区或子分区(或两者)将与PARTITION
表名后面的子句一起使用。当PARTITION
与语句部分中的源表名称一起使用时,
SELECT
仅从分区列表中指定的分区或子分区中选择行。当PARTITION
与语句部分的目标表的名称一起使用时
INSERT
,必须能够将所有选定的行插入到选项后面的分区列表中指定的分区或子分区中。否则,INSERT ...
SELECT
声明失败。有关详细信息和示例,请参阅第 19.5 节,“分区选择”。
对于INSERT
... SELECT
语句,请参阅
第 13.2.5.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”SELECT
以了解可以在ON DUPLICATE KEY UPDATE
子句
中引用列的条件。
SELECT
没有子句
的语句返回行的顺序ORDER BY
是不确定的。这意味着,当使用复制时,无法保证这样的
SELECT
返回行在源和副本上以相同的顺序返回,这可能导致它们之间的不一致。为防止这种情况发生,请始终使用
在源和副本上生成相同行顺序的子句编写INSERT ... SELECT
要复制的语句。ORDER BY
另见第 17.4.1.17 节,“复制和限制”。
由于这个问题,
INSERT ...
SELECT ON DUPLICATE KEY UPDATE
语句
INSERT IGNORE ...
SELECT
被标记为对基于语句的复制不安全。使用基于语句的模式时,此类语句会在错误日志中产生警告,并在使用模式时使用基于行的格式写入二进制日志
MIXED
。(缺陷 #11758262,缺陷 #50439)
另见第 17.1.2.1 节,“基于语句和基于行的复制的优点和缺点”。
使用表级锁INSERT ... SELECT
的存储引擎影响分区表
的语句会锁定目标表的所有分区;MyISAM
但是,只有那些实际从源表中读取的分区才会被锁定。(这不会发生在使用存储引擎的表中,例如InnoDB
使用行级锁定的表。)有关更多信息,请参阅
第 19.6.4 节,“分区和锁定”。