定期将数据加载到表中的最佳方法是什么

时间:2009-12-29 04:38:41

标签: mysql performance myisam load-data-infile

我有一个包含静态表的数据库,需要每周从CSV更新一次。 表是Mysql MyISAM,静态我的意思是它们只用于只读(除非从CVS更新,显然)。

大约有50个表格,每周要重新加载大约200mb的数据。

我可以考虑3种方式:

  1. 截断表
  2. 从文件加载数据
  3. 或者

    1. 为每个表创建一个临时表
    2. 在那里加载数据
    3. 截断(或删除行?)原始表
    4. 从临时表中插入原始表格select *。
    5. 或者

      1. 创建table_new并在那里加载数据
      2. 将原始表重命名为table_old(或完全删除表)
      3. 将table_new重命名为原始表
      4. 你认为最有效的方法是什么?

4 个答案:

答案 0 :(得分:0)

你考虑过使用mysqlimport吗?你可以在这里读到它: http://dev.mysql.com/doc/refman/5.1/en/mysqlimport.html

我可能不会删除原始表格,因为那时你必须重新创建所有外键,索引,约束等等,这是一个混乱和维护的噩梦。重命名表也会导致问题(例如,如果你有表的同义词,我不确定mysql是否有同义词)。

但是,我要做的是在加载数据之前禁用密钥。

ALTER TABLE tbl_name DISABLE KEYS 

换句话说,在加载数据时,您不希望它尝试更新索引,因为这会减慢负载。您希望在加载完成后更新索引。

所以我认为通过将mysqlimport与上面的提示相结合,你应该能够获得非常有效的负载。

答案 1 :(得分:0)

您可以随时INSERT INTO ... ON DUPLICATE KEY UPDATE ...REPLACE INTO ...。你不应该得到任何停机时间(在TRUNCATE和INSERT之间),并且腐败的可能性很小。

小心REPLACE,因为它实际上会删除每条记录并重新插入它,触发你可能拥有的任何触发器(在这种情况下不太可能),但如果你有一个自动的话,还会给你一个新的ID -increment field。

答案 2 :(得分:0)

你的第三个选项是最好的,你可以在导入时在_new表上锁定和禁用键,它会更快。您甚至可以对所有新表进行“批量原子重命名”到“当前的”,如果它们之间存在关系,则停机时间为零。

我假设整个表都包含在每周的cvs更新中(即它们不是增量的)。

答案 3 :(得分:0)

我更喜欢第3种方法,也保留旧表。

  
      
  1. create table_new
  2.   
  3. drop table_old(如果存在)
  4.   
  5. 将表重命名为table_old
  6.   
  7. 将table_new重命名为table
  8.   

这种方法的优点是它快速安全,对读者的影响较小。新表的创建不会影响对现有表的读取。重命名操作更快(仅在myisam的情况下重命名文件),因此停机时间不是那么多。所以客户不会受此影响那么多。您还必须保留旧数据,以防新数据出现问题。

由于您不打算在线更新,我认为如果您使用myisampack会很好。