MySqlDump 的 DISABLE KEYS 对导入没有影响

nua*_*ala 11 mysql innodb mysqldump index backup

我对我之前关于 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;
Run Code Online (Sandbox Code Playgroud)

但实际上这些“注释”是有条件的 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 ? 30 分钟
普通 mysql 导入:放弃,(我只是每天 8 小时获得报酬 >:))

我不禁想到我在这里遗漏了一些非常基本的东西(或者数据库在拖着我)。

Rol*_*DBA 12

你不能依赖DISABLE KEYS;ENABLE KEYS;支持 InnoDB,因为它没有在 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>
Run Code Online (Sandbox Code Playgroud)

这就是为什么没有影响的原因。请回想一下,@jynus 在他的第 7 点回答中提到了同样的事情

还要记住,MyISAM 将数据和索引保存在两个单独的文件中(.MYD 用于数据,.MYI 用于索引),因此禁用和启用索引是微不足道的。InnoDB 将 PRIMARY KEY 和行数据保存在相同的 InnoDB 页面中(通过聚集索引)。二级索引将携带 PRIMARY KEY 作为每个二级索引叶条目的附件。由于数据和索引通过聚集索引交织在一起,到目前为止,还没有人尝试在 InnoDB 中实现DISABLE KEYSENABLE KEYS