Mysql

MySqlDump 的 DISABLE KEYS 對導入沒有影響

  • September 17, 2020

我對我之前關於 Inno-Tables 導入速度的問題進行了跟進(驚喜!)。

場景

我嘗試在合理的時間內在我的本地開發機器上導入一些大型*數據庫轉儲。我們有很多KEYs 附加到表上,這些表已被證明是一個瓶頸,但對我們的實時系統仍然很重要。

在提出上述問題後,我的方法是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 等語句忽略,否則會使用它們。

在上下文中從未提及過 InnoDBALTER 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

引用自:https://dba.stackexchange.com/questions/76565