【问题标题】:Batch MYSQL Inserts with parent relations in transaction在事务中使用父关系批量 MYSQL 插入
【发布时间】:2020-03-12 04:31:10
【问题描述】:

考虑两个表(我已经简化了一点,实际上有更多相关的表和更多的列):

TABLE 'visit'
-------------
- id (auto increment)
- visit_country
- visit_browser

TABLE 'pageview'
----------------
- id
- visit_id (relates to visit.id)
- page_url

每天,我都想在这些表中插入一个访问量约为 100.000 且点击量约为 400.000 的 PHP 数组。加快这个过程的方法是通过

  • 在一个查询中添加多个插入
  • 并将所有查询打包成一个事务。

但是,我的问题是,为了插入综合浏览量,需要父访问的 Last Insert ID。在假设使用一个查询插入 1000 次访问的事务中,我不能再使用 PDO 的 lastInsertId() 方法。

理想情况下,我将所有内容都放在一个事务中。一个不太理想的解决方案是插入所有访问并添加一个引用列,然后执行,检查每次访问获得的 ID,然后使用新事务插入命中。但这远非理想。

解决这个问题的方法是什么? ORM之类的Doctrine是如何解决这个问题的(我这里需要通过PDO依赖原始SQL)?

【问题讨论】:

  • 这个问题太笼统了。在数据库端使用存储过程进行插入?
  • 这里的问题是什么?将整个查询打包成一个事务有什么问题?在普通硬件上插入 100.000 条记录大约需要 2-3 秒。你真的试过了吗?

标签: php mysql pdo


【解决方案1】:

你可以做这样的查询

$sql = "INSERT INTO `visit` (`id`, `visit_country`, `visit_browser`) 
VALUES (NULL, :visit_country, :visit_browser);
INSERT INTO `pageview` (`visit_id`, `page_url`) 
VALUES (NULL, LAST_INSERT_ID(), :page_url)";

准备、绑定参数和执行

【讨论】:

  • 哦,太完美了!现在尝试一下,如果可行,将尽快接受您的回答。
  • @dirk 此代码与使用 PDO 的 lastInsertId() 方法没有什么不同,那么它如何解决 lastInsertId() 没有的任何实际问题?
  • 没错,我不熟悉事务,我认为我仍然需要将插入一起批处理到一个带有事务的查询中,但为了获得速度优势,这似乎不是必需的。刚刚测试了在本地插入 120K 行,没有事务需要 6 分钟,而使用完全相同的单个查询需要 18 秒但包装在事务中。这对我来说已经足够了。抱歉,如果我没有在这里要求正确的东西,但 Ronak 提供的答案实际上帮助了我。
猜你喜欢
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
相关资源
最近更新 更多