【问题标题】:MySQL LOAD DATA INFILE Taking 13 HoursMySQL LOAD DATA INFILE 耗时 13 小时
【发布时间】:2020-02-02 21:38:39
【问题描述】:

我可以在 my.ini 文件中更改什么来加快“加载数据输入”吗?

我有两个 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 timestamp BETWEEN”的 OUTFILE “2014-09-23 00:00:00”和“2014-09-23 23:59:59”。这通常需要 不到 2 分钟。
  2. 在实例 B 上,执行“LOAD DATA INFILE”。这是问题区域 因为大约需要 13 小时。
  3. 在实例 A 上,删除前一天的记录。这可能是另一个
  4. 在实例 B 上,运行统计信息 在实例 B 上,截断表

我还考虑过对表进行分区并仅交换分区。从 5.6 开始支持 EXCHANGE PARTITION,我愿意更新 MySQL,但是,所有文档都讨论了表之间的交换,我无法确认我是否能够在数据库实例之间执行此操作。

实例之间的复制,但由于我过去没有修改过复制,而且这是一项时间敏感的任务,我有点不愿意涉足新领域。

非常感谢任何智慧之言。

【问题讨论】:

  • 您是否尝试在 LOAD DATA INFILE 之前禁用实例 B 上的键?
  • 那么,文件有多大>
  • 不,EXCHANGE PARTITION 不能将分区从一个实例移动到另一个实例。
  • 感谢您澄清@BillKarwin

标签: mysql optimization


【解决方案1】:

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

不是很好的替代方案: 我发现只需复制/移动磁盘上的文件即可轻松移动 MISAM 数据库。如果您剪切/粘贴文件并运行修复表。在您的目标机器上,您可以在不重新启动服务器的情况下执行此操作。只需确保复制所有 3 个文件(.frm、.myd、.myi)

【讨论】:

  • 这种问题解决了,因为我仍然需要创建密钥,否则统计查询将永远持续下去。 LOAD DATA INFILE 现在只需不到 2 分钟,这很棒。但是,当我尝试在 user_key 列上创建索引时,进程将永远处于“复制到 tmp 表”的进程状态
  • 你有足够的磁盘空间吗?是否检查了 my.ini 参数(如 key_buffer_size 等,请参阅here) 能否提供索引创建查询?
【解决方案2】:
  1. 以完美的 PK 顺序加载 DATA INFILE,进入一个只有 PK 定义的表,因此还没有二级索引。导入后,一次添加所有二级索引,使用“ALTER TABLE mytable ALGORITHM=INPLACE, LOCK=NONE, ADD KEY ...”。 考虑单独添加回每个相关框的二级索引,而不是通过复制 (sql_log_bin=0),以防止复制滞后。

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

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

【讨论】:

    猜你喜欢
    • 2013-10-03
    • 2012-10-05
    • 2010-11-17
    • 1970-01-01
    • 2017-07-21
    • 2012-06-01
    • 2011-09-01
    • 1970-01-01
    相关资源
    最近更新 更多