MySqlDump 的 DISABLE KEYS 對導入沒有影響
我對我之前關於 Inno-Tables 導入速度的問題進行了跟進(驚喜!)。
場景
我嘗試在合理的時間內在我的本地開發機器上導入一些大型*數據庫轉儲。我們有很多
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)'
從轉儲中刪除所有 - 行、導入轉儲並ADD KEY 'foo' ...
隨後執行腳本的行為相同。我觀察
到手動刪除密鑰、導入和重新添加密鑰然後依靠條件
DISABLE KEYS
語句創建我的方法要快得多mysqldump
手動編輯轉儲 + mysql 導入 + 添加鍵 = 15+8+8 ≈ 30min
普通 mysql 導入:放棄,(我只是得到 8 小時/天的報酬>:))
我不禁想我在這裡遺漏了一些非常基本的東西(或者數據庫在欺騙我)。
你不能依賴InnoDB
DISABLE KEYS;
,ENABLE KEYS;
因為它沒有在 InnoDB 儲存引擎中實現。執行ALTER TABLE ... DISABLE KEYS;
並ALTER TABLE ... ENABLE KEYS;
為 MyISAM 設計。正如它在MySQL 文件中ALTER TABLE
所說:如果您在 MyISAM 表上使用 ALTER TABLE,則所有非唯一索引都將在單獨的批處理中創建(與 REPAIR TABLE 一樣)。當您有許多索引時,這應該會使 ALTER TABLE 更快。
對於 MyISAM 表,可以顯式控制密鑰更新。使用 ALTER TABLE … DISABLE KEYS 告訴 MySQL 停止更新非唯一索引。然後使用 ALTER TABLE … ENABLE KEYS 重新創建失去的索引。MyISAM 使用一種特殊算法來執行此操作,該算法比逐個插入密鑰要快得多,因此在執行批量插入操作之前禁用密鑰應該會大大加快速度。除了前面提到的權限之外,使用 ALTER TABLE … DISABLE KEYS 還需要 INDEX 權限。
當非唯一索引被禁用時,它們會被 SELECT 和 EXPLAIN 等語句忽略,否則會使用它們。
在上下文中從未提及過 InnoDB
ALTER TABLE ... DISABLE/ENABLE KEYS;
即使您
ALTER TABLE ... DISABLE KEYS;
針對 InnoDB 表執行,它也會生成警告: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 將數據和索引保存在兩個單獨的文件中(.MYD 用於數據,.MYI 用於索引),因此禁用和啟用索引是微不足道的。InnoDB 將 PRIMARY KEY 和行數據保存在相同的 InnoDB 頁面中(通過聚集索引)。二級索引將攜帶 PRIMARY KEY 作為每個二級索引葉條目的附件。由於數據和索引通過聚集索引交織在一起,到目前為止,還沒有人嘗試在 InnoDB中實現
DISABLE KEYS
和。ENABLE KEYS