13.2.5.1 INSERT ... SELECT 语句

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] ...

使用插入...选择,您可以根据SELECT语句的结果快速向 table 中插入许多行,该语句可以从一个或多个 table 中进行选择。例如:

INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

以下条件适用于插入...选择条语句:

  • 指定IGNORE可忽略将导致重复键冲突的行。

  • INSERT语句的目标 table 可能出现在查询的SELECT部分的FROM子句中。但是,您不能插入 table 并在子查询中从同一 table 中选择。

从同一 table 中选择并插入到同一 table 中时,MySQL 创建一个内部临时 table 来保存SELECT中的行,然后将这些行插入目标 table 中。但是,当tTEMPORARYtable 时,不能使用INSERT INTO t ... SELECT ... FROM t,因为TEMPORARYtable 不能在同一语句中被两次引用。参见第 8.4.4 节“ MySQL 中的内部临时 table 使用”第 B.4.6.2 节,“临时 table 问题”

  • AUTO_INCREMENT列照常工作。

  • 为了确保二进制日志可用于重新创建原始 table,MySQL 不允许并发插入插入...选择语句(请参见第 8.11.3 节“并发插入”)。

  • 为了避免当SELECTINSERT引用同一 table 时列引用存在歧义,请为SELECT部分中使用的每个 table 提供唯一的别名,并使用适当的别名来限定该部分中的列名。

您可以通过 table 名后面的PARTITION选项显式选择要使用源 table 或目标 table(或两者)的分区或子分区(或两者)。在语句的SELECT部分中将PARTITION与源 table 的名称一起使用时,仅从其分区列 table 中命名的分区或子分区中选择行。如果在语句的INSERT部分中将PARTITION与目标 table 的名称一起使用,则必须可以将所有选择的行插入到该选项之后的分区列 table 中命名的分区或子分区中。否则,INSERT ... SELECT语句将失败。有关更多信息和示例,请参见第 22.5 节“分区选择”

对于插入...选择语句,请参见第 13.2.5.2 节“在重复密钥更新语句上插入...”以了解在ON DUPLICATE KEY UPDATE子句中可以引用SELECT列的条件。

没有ORDER BY子句的SELECT语句返回行的 Sequences 是不确定的。这意味着,在使用复制时,无法保证这样的SELECT返回主服务器和从服务器上的行的 Sequences 相同,这可能导致它们之间的不一致。为了防止这种情况的发生,请始终使用要在主服务器和从属服务器上产生相同行 Sequences 的ORDER BY子句编写要复制的INSERT ... SELECT语句。另请参见第 16.4.1.17 节,“复制和限制”

由于此问题,对于基于语句的复制,插入...选择重复的密钥更新插入忽略...选择语句被标记为不安全。当使用基于语句的模式时,此类语句在错误日志中产生警告,而在使用MIXED模式时,则使用基于行的格式将其写入二进制日志。 (缺陷#11758262,缺陷#50439)

另请参见第 16.2.1.1 节,“基于语句的复制和基于行的复制的优缺点”

INSERT ... SELECT语句使用诸如 table 级锁之类的存储引擎来影响分区 table,该存储引擎采用 table 级锁来锁定目标 table 的所有分区。但是,只有那些实际从源 table 读取的分区才被锁定。 (对于使用诸如InnoDB之类的存储引擎并采用行级锁定的 table,不会发生这种情况。)有关更多信息,请参见第 22.6.4 节“分区和锁定”