通过脚本在MySQL中添加新记录

时间:2012-05-29 20:58:06

标签: mysql sql perl optimization query-optimization

我有一个大型数据库,我试图通过perl更新。要添加的信息来自我无法控制的csv文件(但它是可信的 - 它来自我们公司的不同部分)。对于文件中的每个记录,我需要添加它(如果它不存在)或不执行任何操作(如果它存在)。添加记录包含通常的INSERT INTO,但在此之前可以针对特定条目运行,必须运行特定的UPDATE

让我们说,为了具体起见,该文件有10,000个条目,但其中90%已经在数据库中。导入记录的最有效方法是什么?我可以看到一些明显的方法:

  • 从数据库中提取此类型的所有记录,然后检查文件中的每个条目是否有成员资格。缺点:大量的数据传输,可能足以让服务器停机。
  • 读入文件中的条目,并仅针对那些带有RLIKE 'foo|bar|baz|...'查询(或stuff = 'foo' || stuff = 'bar' || ...查询的记录发送查询,但这看起来更糟糕)。缺点:巨大的查询,可能足以阻塞服务器。
  • 读入文件,发送每个条目的查询,然后在适当的时候添加。缺点:成千上万的查询,非常缓慢。

UPDATE要求外,这似乎是一个相当标准的问题,可能有一个标准的解决方案。如果有的话,可以通过在auto_increment主键上适当使用测试来适应我的情况。

2 个答案:

答案 0 :(得分:1)

标准解决方案是使用INSERT IGNORE,如果插入因约束而失败,则不会引发错误。这对您没有多大用处,因为在您知道UPDATE将起作用之前,它不会让您有机会执行INSERT。但是,如果您之后可以进行更新,这是理想的:只需INSERT IGNORE每条记录,然后UPDATE成功。

如果记录已存在,则意味着具有匹配唯一键的记录已存在于数据库中,因此我不理解RLIKE提案必然会很慢。

我会使用Perl为每条记录使用SELECT count(*) FROM table WHERE key = ? grep CSV文件,并删除结果为非零的任何内容。

然后,只需对过滤后的CSV数据中的所有内容执行UPDATEINSERT

答案 1 :(得分:0)

如果在迭代列表时不断刷新数据,则无需超时服务器。