我有一个事件数据库,每晚都会更新。单个事件包含三个(或更多)表的信息。最近,更新量导致我的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。)
答案 0 :(得分:2)
不要使用自动递增列 - 在插入之前预先分配您的引用ID。这样,您就可以使用批量插入并删除依赖项。
更新
从数据库中选择任何现有ID(理想情况下,对所有已知数据进行单一选择)。
将数据加入以插入任何已知的ID。 (计算每个项目的一个键,它与数据库中表的主键相对应,使用它来更新数据库中id的项目) - 您希望最终将数据拆分为您知道的项目数据库,因此具有已知的id - 和数据库中不存在的数据,因此需要密钥分配。我假设你的表有一个不只是id的主键 - 否则数据库知道你已经拥有数据库中的数据了。
将新ID分配给任何没有ID的记录。
批量替换数据库中的数据(使用单个语句插入多行)。
答案 1 :(得分:2)
不了解MySQL的详细信息,但任何自尊的RDBMS都有所谓的“序列”实体,这些实体可用作适合表主键的唯一值的来源。
下面是使用序列来解决问题的方法,这是我多次遇到的问题。使用伪代码:
locations
,event_info
,event_times
; INSERT INTO locations
; INSERT INTO event_info
; INSERT INTO event_times
; COMMIT
交易,如果一切顺利的话。否则,ROLLBACK
交易。在一次交易中制作所有INSERT
是至关重要的。
要进一步增强,您可以批量查询。
更新符合您在INSERT
之前可能预先存在数据的要求
如果您的传入更新始终包含整个数据集:即location,event_info和event_times:然后使用上述方法,只删除表中的旧记录实例。这假设您可以使用除主键之外的某些数据(该数据称为域级主键)SELECT
旧实例。不要忘记在同一笔交易中制作DELETE
!