MySQL LOAD DATA INFILE需要13个小时

时间:2014-09-24 16:58:24

标签: mysql optimization

我可以在my.ini文件中更改任何内容以加快" LOAD DATA INFILE"?

我有两个MySQL 5.5实例,每个实例都有一个相同的表结构如下:

CREATE TABLE `log_access` (
  `_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `type_id` int(11) NOT NULL,
  `building_id` int(11) NOT NULL,
  `card_id` varchar(15) NOT NULL,
  `user_key` varchar(35) DEFAULT NULL,
  `user_name` varchar(25) DEFAULT NULL,
  `user_validation` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`_id`),
  KEY `log_access__user_key_timestamp` (`user_key`,`timestamp`)
  KEY `log_access__timestamp` (`timestamp`)
) ENGINE=MyISAM

每天我需要将前一天的数据从实例A移动到实例B,后者包含大约2500万条记录。目前我正在做以下事情:

  1. 在实例A上,使用" WHERE时间戳BETWEEN生成一个OUTFILE ' 2014-09-23 00:00:00' AND' 2014-09-23 23:59:59'。这通常需要 不到2分钟。
  2. 在实例B上,执行" LOAD DATA INFILE"。这是问题所在 因为大约需要13个小时。
  3. 在实例A上,删除前一天的记录。这可能是另一个
  4. 在实例B上,运行stats在实例B上,截断表
  5. 我还考虑过对表进行分区,只是交换分区。从5.6开始支持EXCHANGE PARTITION,我愿意更新MySQL,但是,所有文档都讨论了表之间的交换,我还没有能够确认我能够在数据库实例之间做到这一点。

    实例之间的复制,但由于我过去没有修复复制,这是一个时间敏感的任务,我有点不愿意进入新的水域。

    任何智慧的话都非常赞赏。

2 个答案:

答案 0 :(得分:0)

创建没有PRIMARY KEY和_id列的表,并在LOAD DATA INFILE完成后添加这些表。 MySQL检查每个INSERT的PRIMARY KEY完整性,所以我认为你可以在这里获得很多性能。使用MariaDB,您可以禁用密钥,但我认为这不会对某些存储引擎起作用(请参阅here

不是非常漂亮的替代: 我发现通过复制/移动磁盘上的文件来移动MYISAM数据库非常容易。如果您剪切/粘贴文件并运行REPAIR TABLE。在目标计算机上,您无需重新启动服务器即可执行此操作。只需确保复制所有3个文件(.frm,.myd,.myi)

答案 1 :(得分:0)

  1. 以完美的PK顺序装入DATA INFILE,将其装入仅具有PK定义的表,因此尚无辅助索引。导入后,立即添加所有二级索引,并带有“ ALTER TABLE mytable ALGORITHM = INPLACE,LOCK = NONE,ADD KEY ...”。 考虑单独在每个涉及的框上添加二级索引,而不是通过复制(sql_log_bin = 0),以防止复制滞后。

  2. 考虑使用分区表,这样您就可以并行地为每个分区运行“ LOAD DATA INFILE”。 (适用于RANGE和HASH分区,因为单独的tsv文件(每个分区一个或多个)很容易为它们准备)

MariaDB还没有变体“ INTO mytable PARTITION(p000)”。 您可以先加载到一个单独的表中,然后再交换分区,但是MariaDB还没有“ WITHOUT VALIDATION”。