約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
し、パフォーマンスの比較に使用しています。
欠点は、全体の実行時間しか取得できないため、結果を取得するために完全なインポートが完了するのを待つ必要があることです。
これまでの私の結果:
- 10 000行:<1秒
- 100 000行:10秒
- 30万行:40秒
- 200万行:18分
- 300万行:26分
- 400万行:(2時間後にキャンセル)
「クックブック」の解決策はないようで、自分で設定の最適な組み合わせを見つける必要があります。
セットアップで何を変更するかについての提案に加えて、インポートプロセスのベンチマークを改善したり、何が起こっているのか、ボトルネックがどこにあるのかについてより多くの洞察を得たりする方法についての情報もありがたいです。
私は変更している設定のドキュメントを読み込もうとしましたが、再び副作用を認識していません。不適切な値を選択するとパフォーマンスが低下する可能性さえあります。
今のところ、MyISAM
インポート中に使用するチャットからの提案を試し、後でテーブルエンジンを変更します。
私はこれを試したいのですが、今のところ私のDROP TABLE
クエリも完了するまでに数時間かかります。(私の設定が最適ではない別の指標のようです)。
追加情報:
私が現在使用しているマシンには、8 GBのRAMと5400RPMのソリッドステートハイブリッドハードドライブが搭載されています。
問題のテーブルから古いデータを削除することも目的としていますが、
a)開発中の
テストautomatic data cleanup feature
と、
b)サーバーがクラッシュした場合に2番目のサーバーを交換用として使用するために、いくらか高速にインポートする必要があります(必要です) -最新のデータ、最後のインポートに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のクラッシュではない)が発生した場合、データが静かに破損する可能性があります。