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 twhentis aTEMPORARYtable,因为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 节,“分区和锁定”。