Я борюсь с массовым импортом довольно большой таблицы InnoDB, состоящей примерно из 10 миллионов строк (или 7 ГБ) (что для меня является самой большой таблицей, с которой я когда-либо работал).
Я провел некоторое исследование, как улучшить скорость импорта 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
файле.
В настоящее время я тестирую свои настройки с меньшими «тестовыми дампами» с 2 миллионами, 3 миллионами,… строками каждый и использую их time import_script.sh
для сравнения производительности.
Недостатком является то, что я получаю только общее время выполнения, поэтому мне приходится ждать завершения полного импорта, чтобы получить результат.
Мои результаты пока:
- 10 000 строк: <1 секунда
- 100 000 строк: 10 секунд
- 300 000 строк: 40 секунд
- 2 миллиона строк: 18 минут
- 3 миллиона строк: 26 минут
- 4 миллиона строк: (отменено через 2 часа)
Похоже, решения для «поваренной книги» не существует, и нужно самостоятельно определить оптимальное сочетание настроек.
Помимо предложений о том, что нужно изменить в моей настройке, я также был бы очень признателен за дополнительную информацию о том, как лучше оценить процесс импорта / получить более полное представление о том, что происходит и где может быть узкое место.
Я попытался прочитать документацию по изменяемым настройкам, но, опять же, я не знаю никаких побочных эффектов и могу ли я даже снизить производительность при неправильно выбранном значении.
На данный момент я хотел бы попробовать предложение из чата, чтобы использовать MyISAM
во время импорта и впоследствии изменить таблицу движка.
Я хотел бы попробовать это, но на данный момент мой DROP TABLE
запрос также занимает несколько часов, чтобы закончить. (Что является еще одним показателем, мой параметр меньше оптимального).
Дополнительная информация:
Машина, которую я сейчас использую, имеет 8 ГБ ОЗУ и твердотельный гибридный жесткий диск с 5400 об / мин.
Хотя мы также стремимся удалить устаревшие данные из таблицы, о которой идет речь, мне все же требуется несколько быстрый импорт в
а) тестирование automatic data cleanup feature
во время разработки и
б) в случае сбоя нашего сервера, мы хотели бы использовать наш второй сервер в качестве замены (который требует -данные данные, последний импорт занял более 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
чтобы показать нам структуру таблицы этой таблицы с 10 миллионами строк.
innodb_doublewrite = 0
), ваша установка MySQL не является безопасной при сбое: если у вас сбой питания (не сбой MySQL), ваши данные могут быть незаметно повреждены.