棘手的MySQL批量查询

时间:2012-01-17 21:00:23

标签: php mysql performance batch-processing

我有一个事件数据库,每晚都会更新。单个事件包含三个(或更多)表的信息。最近,更新量导致我的MySQL引擎非常缓慢,以至于在插入新事件时我的其他查询被冻结。为了加快速度,我想进行一系列批量查询,而不是分别进行每个查询,我觉得这是开销的很大一部分。

问题是因为数据分布在几个表中,这是我要插入单个事件所必须做的事情:

   (in Mysql) INSERT INTO 'locations' (...) VALUES (...) ON DUPLICATE KEY UPDATE ...
   (in php get the last inserted id into variable $locationID)
   (in Mysql) INSERT INTO 'event_info' (...) VALUES ($locationID, ...) ON DUPLICATE KEY UPDATE...
   (in php get the last inserted id into variable $eventID)
   (in Mysql) INSERT INTO 'event_times' (...) VALUES ($eventID, ...) ON DUPLICATE KEY UPDATE...

我不是在设计表格时寻求帮助,但是你可以看到插入单个事件需要至少三个插入,每个插入取决于从前一个获取id。这就是为什么我不知道从哪里开始将其作为批处理请求。将此过程设计为批量请求的任何帮助都很棒,谢谢!

编辑:我之前可能已经拥有位置或事件信息,这就是ON DUPLICATE KEY UPDATE部分存在的原因,如果它已经在数据库中,我会得到旧的ID。直到插入时我才知道它是新数据还是已存在于数据库中。 (因为除非我误解,否则我不能做那些预先分配ID的事情,因为每次都会假设一个新的id。)

2 个答案:

答案 0 :(得分:2)

不要使用自动递增列 - 在插入之前预先分配您的引用ID。这样,您就可以使用批量插入并删除依赖项。

更新

  1. 从数据库中选择任何现有ID(理想情况下,对所有已知数据进行单一选择)。

  2. 将数据加入以插入任何已知的ID。 (计算每个项目的一个键,它与数据库中表的主键相对应,使用它来更新数据库中id的项目) - 您希望最终将数据拆分为您知道的项目数据库,因此具有已知的id - 和数据库中不存在的数据,因此需要密钥分配。我假设你的表有一个不只是id的主键 - 否则数据库知道你已经拥有数据库中的数据了。

  3. 将新ID分配给任何没有ID的记录。

  4. 批量替换数据库中的数据(使用单个语句插入多行)。

答案 1 :(得分:2)

不了解MySQL的详细信息,但任何自尊的RDBMS都有所谓的“序列”实体,这些实体可用作适合表主键的唯一值的来源。

下面是使用序列来解决问题的方法,这是我多次遇到的问题。使用伪代码:

  1. 开始交易
  2. 从某个序列中选择3个下一个值。同样,任何自尊的RDBMS都将保证“序列的下一个值”的每个查询都将返回唯一值,适合用作主键。三个选定的值将用于locationsevent_infoevent_times;
  3. 中新记录的主键
  4. 使用第1步的值执行INSERT INTO locations;
  5. 使用第1步中的值执行INSERT INTO event_info;
  6. 使用第1步中的值执行INSERT INTO event_times;
  7. COMMIT交易,如果一切顺利的话。否则,ROLLBACK交易。
  8. 在一次交易中制作所有INSERT是至关重要的。 要进一步增强,您可以批量查询。

    更新符合您在INSERT之前可能预先存在数据的要求

    如果您的传入更新始终包含整个数据集:即location,event_info和event_times:然后使用上述方法,只删除表中的旧记录实例。这假设您可以使用除主键之外的某些数据(该数据称为域级主键)SELECT旧实例。不要忘记在同一笔交易中制作DELETE