我在批量导入一个由大约1000万行(或7GB)组成的相当大的InnoDB表时遇到了麻烦(对我来说,这是迄今为止我使用过的最大表)。
我做了一些研究来提高Inno的导入速度,目前我的设置如下所示:
/etc/mysql/my.cnf/
[...]
innodb_buffer_pool_size = 7446915072 # ~90% of memory
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_thread_concurrency=0
innodb_doublewrite = 0
innodb_log_file_size = 1G
log-bin = ""
innodb_autoinc_lock_mode = 2
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_instances=8
import is done via bash script, here is the mysql code:
SET GLOBAL sync_binlog = 1;
SET sql_log_bin = 0;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';
LOAD DATA LOCAL INFILE '$filepath' INTO TABLE monster
COMMIT;
数据以CSV
文件形式提供。
目前,我使用较小的“测试转储”测试我的设置,每个转储分别有200万,300万,…行,并用于time import_script.sh
比较性能。
缺点是我只能获得整体运行时间,因此我必须等待完整的导入完成才能获得结果。
到目前为止,我的结果是:
- 1万行:<1秒
- 10万行:10秒
- 30万行:40秒
- 200万行:18分钟
- 300万行:26分钟
- 400万行:(2小时后取消)
似乎没有“食谱”解决方案,因此必须自己找出最佳设置组合。
除了提出有关更改设置方面的建议外,我还将非常感谢您提供更多信息,以了解如何更好地对导入过程进行基准测试/获得更多信息,了解正在发生的事情以及可能出现的瓶颈。
我试图阅读有关要更改的设置的文档,但随后我又不知道有任何副作用,甚至可能因选择错误的值而降低性能。
目前,我想尝试从聊天中获得的建议,以便MyISAM
在导入和更改表引擎之后使用。
我想尝试一下,但目前我的DROP TABLE
查询还需要几个小时才能完成。(这似乎是我的设置低于最佳指标的另一个指标)。
附加信息:
我当前正在使用的计算机具有8GB的RAM和一个带5400RPM的固态混合硬盘。
虽然我们还打算从相关表中删除过时的数据,但我仍然需要快速导入到
a)automatic data cleanup feature
开发过程中进行测试,以及
b)万一服务器崩溃,我们希望使用第二台服务器作为替代(需要升级)最新数据,最后一次导入耗时超过24小时)
mysql> SHOW CREATE TABLE monster\G
*************************** 1. row ***************************
Table: monster
Create Table: CREATE TABLE `monster` (
`monster_id` int(11) NOT NULL AUTO_INCREMENT,
`ext_monster_id` int(11) NOT NULL DEFAULT '0',
`some_id` int(11) NOT NULL DEFAULT '0',
`email` varchar(250) NOT NULL,
`name` varchar(100) NOT NULL,
`address` varchar(100) NOT NULL,
`postcode` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`country` int(11) NOT NULL DEFAULT '0',
`address_hash` varchar(250) NOT NULL,
`lon` float(10,6) NOT NULL,
`lat` float(10,6) NOT NULL,
`ip_address` varchar(40) NOT NULL,
`cookie` int(11) NOT NULL DEFAULT '0',
`party_id` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '2',
`creation_date` datetime NOT NULL,
`someflag` tinyint(1) NOT NULL DEFAULT '0',
`someflag2` tinyint(4) NOT NULL,
`upload_id` int(11) NOT NULL DEFAULT '0',
`news1` tinyint(4) NOT NULL DEFAULT '0',
`news2` tinyint(4) NOT NULL,
`someother_id` int(11) NOT NULL DEFAULT '0',
`note` varchar(2500) NOT NULL,
`referer` text NOT NULL,
`subscription` int(11) DEFAULT '0',
`hash` varchar(32) DEFAULT NULL,
`thumbs1` int(11) NOT NULL DEFAULT '0',
`thumbs2` int(11) NOT NULL DEFAULT '0',
`thumbs3` int(11) NOT NULL DEFAULT '0',
`neighbours` tinyint(4) NOT NULL DEFAULT '0',
`relevance` int(11) NOT NULL,
PRIMARY KEY (`monster_id`),
KEY `party_id` (`party_id`),
KEY `creation_date` (`creation_date`),
KEY `email` (`email`(4)),
KEY `hash` (`hash`(8)),
KEY `address_hash` (`address_hash`(8)),
KEY `thumbs3` (`thumbs3`),
KEY `ext_monster_id` (`ext_monster_id`),
KEY `status` (`status`),
KEY `note` (`note`(4)),
KEY `postcode` (`postcode`),
KEY `some_id` (`some_id`),
KEY `cookie` (`cookie`),
KEY `party_id_2` (`party_id`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=13763891 DEFAULT CHARSET=utf8
SHOW CREATE TABLE yourtable\G
以向我们展示该1000万行表的表结构。
innodb_doublewrite = 0
),您的MySQL安装将不会崩溃安全:如果发生电源故障(而非MySQL崩溃),则数据可能会被无提示破坏。