【问题标题】:Is there a better way to return last inserted ID for multi insert?有没有更好的方法来返回最后插入的 ID 以进行多插入?
【发布时间】:2011-10-17 07:50:07
【问题描述】:

我正在使用 PHP 向我的 MySQL 数据库添加 95 个新行并返回新行 ID。执行时间大约需要 24 秒。如果超过 30 秒,PHP 将停止执行(默认时间限制为 30 秒)。

我需要为插入的每一行返回行 ID,以便我可以使用它来安装相关数据。

我目前的解决方案是这样的:

  /* snippets from my class objects to illustrate my code */

  // This foreach takes 24 seconds on just 95 rows
  foreach($list as $row) {
    $id = $this->importRows($sid,$table)

    array_push($id_list,$id);
  }

  /* PDO insertion */
  protected function importRows($row) {
    $sql = "INSERT INTO my_table (name, colour)
            VALUES $row['name'], $row['colour']";

    $result = $this->db->exec($sql);
    return $this->db->lastInsertId();
  }

为了减少插入时间,我希望我可以在一个查询中插入多行 根据MySQL(向下滚动到红色的林德和重要的词)它说:

如果您使用单个 INSERT 语句插入多行, LAST_INSERT_ID() 返回为第一个插入生成的值 仅行。

他们建议的解决方案是创建另一个表并在其中插入新 ID,然后我可以在最后通过 select 语句获取新 ID。

有人研究过类似的解决方案吗?有什么建议可以让我更有效地完成这项工作吗?

【问题讨论】:

标签: php mysql pdo


【解决方案1】:

这是我在这种情况下使用的技巧:

$query = "INSERT INTO my_table (name, colour) VALUES";
$i = 0;
foreach( $rows as $row ) {
    if( $i ) $query .= ',';
    $query .= " ( $row[ 'name' ],
              IF( @id$i := LAST_INSERT_ID(), $row[ 'colour' ], $row[ 'colour' ] ) )";
    ++$i;
}
$result = $this->db->exec( $query );

然后有一个这样的查询来获取 id:

SELECT @id1, @id2, @id3, ...

【讨论】:

  • 您可以使用@ids:=CONCAT(@ids, ',' ,LAST_INSERT_ID()) 获取未知的 id 计数! @史蒂文
【解决方案2】:
  1. 锁表
  2. 使用一个“插入”添加您的数据
  3. 解锁表
  4. 获取最后一个插入ID
  5. 可以计算其他 id:id[n]=last_insert_id+n,其中 n 是您插入的行号

【讨论】:

  • 快速说明:“lastInsertId”似乎有可能返回第一行或已插入的最后一行的 id。这取决于服务器配置中的某些内容。我不知道这可以在哪里改变,但我有两种行为。不过,它是固定在系统基础上的,所以如果你在尝试时得到第一个,你总是会得到第一个 - 不是随机的 :)
  • -1 这很容易出错。如果某些insert stmt 失败,则数字将关闭。更不用说并发事务了。更不用说锁定表绝不是一个好主意。
  • 3.和4.不应该互换吗?
  • @Adrian,为什么锁表是个坏主意? MySql 上的LAST_INSERT_ID() 是否仅限于当前会话?因此没有必要锁定表格?
猜你喜欢
  • 2020-12-11
  • 2020-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-06
  • 2014-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多