Inno-Tablesでのインポート速度について、 私の前の質問 についてフォローアップがあります(驚き!)。
シナリオ
妥当な時間内にローカルの開発用マシンにbig *データベースのダンプをインポートしようとしています。テーブルには多くのKEY
sがアタッチされていますが、これらはボトルネックであることが判明していますが、ライブシステムでは依然として重要です。
上記の質問をした後の私のアプローチは、ダンプから_KEY ...
_ステートメントを削除し、キーをインポートして再度追加することでした。
しかし、現在のダンプを編集してローカルにインポートすることがよくあり、これらの面白い "コメント"(_disable/enable keys
_- lines)を偶然見つけました
_--
-- Dumping data for table `monster`
--
LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT … INSERT … INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;
_
しかし、実際にはこれらの「コメント」は条件付きのMySql-Statements
それは私にとってはニュースでしたが、出力フォーム__mysql --version
_を考えると、問題ありません。mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3
私が想定していること
テーブルはロックされています(問題ありません。開発者の私だけです)。次に、テーブルスキーマで定義されているキーが無効になり、データがインポートされ、キーが有効になります。
したがって、「データ挿入」フェーズでは、キーに時間を浪費することなく、すべてのデータが挿入された後で調べます。
これは、すべてのKEY 'foo' (foo)'
- lineをダンプから削除し、ダンプをインポートして、後で_ADD KEY 'foo' ...
_を使用してスクリプトを実行する場合と同じ動作であると考えています。
私が観察するもの
キーを手動で削除し、キーをインポートして再度追加してから、条件付きの_DISABLE KEYS
_ステートメントを使用して作成した方がずっと高速ですmysqldump
ダンプの手動編集+ mysqlインポート+キーの追加= 15 + 8 + 8≈30分
プレーンなmysqlインポート:あきらめました(1日8時間だけ支払いを受けています> :))
私は仕方がないのですが、ここには非常に基本的な何かが欠けていると思います(またはデータベースが私を荒らしています)。
InnoDBストレージエンジンに実装されていないため、InnoDBのDISABLE KEYS;
およびENABLE KEYS;
は信頼できません。実行中のALTER TABLE ... DISABLE KEYS;
およびALTER TABLE ... ENABLE KEYS;
はMyISAM用に設計されました。 MySQL Documentation for ALTER TABLE
にあるように:
MyISAMテーブルでALTER TABLEを使用する場合、一意でないインデックスはすべて、別のバッチで作成されます(REPAIR TABLEの場合と同様)。これにより、多くのインデックスがある場合に、ALTER TABLEがはるかに高速になります。
MyISAMテーブルの場合、キーの更新を明示的に制御できます。 ALTER TABLE ... DISABLE KEYSを使用して、一意でないインデックスの更新を停止するようMySQLに指示します。次に、ALTER TABLE ... ENABLE KEYSを使用して、欠落しているインデックスを再作成します。 MyISAMは、キーを1つずつ挿入するよりもはるかに高速な特別なアルゴリズムを使用してこれを行うため、一括挿入操作を実行する前にキーを無効にすると、かなりのスピードアップが得られます。 ALTER TABLE ... DISABLE KEYSを使用するには、前述の特権に加えてINDEX特権が必要です。
非一意性インデックスは無効になりますが、SELECTやEXPLAINなどのステートメントを使用しない場合は無視されます。
ALTER TABLE ... DISABLE/ENABLE KEYS;
に関連してInnoDBについて言及されたことはありません
InnoDBテーブルに対してALTER TABLE ... DISABLE KEYS;
を実行しても、警告が生成されます。
mysql> show create table mytimes\G
*************************** 1. row ***************************
Table: mytimes
Create Table: CREATE TABLE `mytimes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`totalTime` int(11) NOT NULL,
`totalTimeDesc` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------------------------------+
| Note | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
そのため、影響はありません。 @ jynusが同じことを箇条書き7 の彼の回答で述べたことを思い出してください。
また、MyISAMはデータとインデックスを2つの個別のファイル(データの場合は.MYD、インデックスの場合は.MYI)に保持するため、インデックスを無効または有効にするのは簡単です。 InnoDBは、プライマリキーと行データを同じInnoDBページに(クラスタ化インデックスを介して)保持します。セカンダリインデックスは、すべてのセカンダリインデックスリーフエントリへのアタッチメントとしてプライマリキーを保持します 。データとインデックスはクラスター化インデックスを介して絡み合っているため、現在のところ、InnoDBにDISABLE KEYS
とENABLE KEYS
を実装しようとした人はいません。