2012-02-07 57 views
1

我有一个刮板,它访问许多网站,并发现即将发生的事件和另一个脚本实际上应该把它们放在数据库中。目前插入数据库是我的瓶颈,我需要一个更快的方式来批量查询,而不是我现在拥有的。棘手的MySQL批处理设计

是什么让这个棘手的是,一个单一的事件有三个表中的数据,它们之间有相互的键。要插入单个事件,我插入位置或获取该位置的已经存在的ID,然后插入实际的事件文本和其他数据,或者获取事件ID(如果它已存在的话)(某些重复每周等),最后插入日期与位置和事件id。

我不能使用REPLACE INTO,因为它会使用这些相同的密钥来隔离较旧的数据。我在Tricky MySQL Batch Query问过这个问题,但是如果TLDR的结果是我必须检查哪些键已经存在,请预先分配那些不存在的,然后为每个表做一个插入(即在php中完成大部分工作)。这很好,但问题是,如果一次处理多个批次,他们可能会选择预先分配相同的密钥,然后相互覆盖。无论如何,因为那么我可以回到这个解决方案吗?批次必须能够并行工作。

我现在所拥有的只是关闭批处理持续时间的索引并分别插入每个事件,但我需要更快的一些事情。任何想法都会对这个棘手的问题有所帮助。 (这些表是InnoDB现在...可以交易帮助解决这一切?)

回答

1

我建议从Mysql Lock Tables开始,您可以使用它来防止其他会话在插入数据时写入表中。

例如,你可能会做同样的事情到这个

mysql_connect("localhost","root","password"); 
mysql_select_db("EventsDB"); 
mysql_query("LOCK TABLE events WRITE"); 
$firstEntryIndex = mysql_insert_id() + 1; 
/*Do stuff*/ 
... 
mysql_query("UNLOCK TABLES); 

上面做了两两件事。首先,锁定表格,阻止其他会话写入,直到完成并解锁语句运行。第二件事是$ firstEntryIndex;这是将在任何后续插入查询中使用的第一个键值。

+0

嗯,这肯定会解决数据能够相互覆盖的问题,但是整个目标是让所有事情都变得更快,因此一次只限制一个进程似乎是退步了。 – hackartist 2012-02-07 19:36:09

+0

它不会将进程限制为单个实例,只要确保您可以基于单个密钥进行处理而不会有数据丢失/损坏的风险。您使用哪种方法不可能在不影响效率的情况下为锁表的预处理和安全性提供灵活性。 – CBusBus 2012-02-07 19:53:08