我正试图通过临时禁用其索引来加速InnoDB表中的批量插入:
ALTER TABLE mytable DISABLE KEYS;
但它提供了警告:
+-------+------+-------------------------------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------------------------------+
| Note | 1031 | Table storage engine for 'mytable' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)
我们如何禁用索引?
在进行批量插入时,有哪些替代方法可以避免使用索引?
我们如何加快这个过程?
答案 0 :(得分:30)
您是否尝试过以下操作?
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
来自MySQL参考文献https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html
请参阅“批量数据加载提示”
部分答案 1 :(得分:28)
有一个很好的理由说明为什么你不能在InnoDB表上执行DISABLE KEYS
; InnoDB不是为了使用而设计的,MyISAM就是。
实际上,这是重新加载mysqldump时会发生的事情:
通过写锁定,您将看到MyISAM表的CREATE TABLE
。
在运行所有批量插入之前,已完成对ALTER TABLE ... DISABLE KEYS
的调用。
这样做是关闭MyISAM表中的二级索引。
然后,完成批量插入。在执行此操作时,将禁用MyISAM表中的PRIMARY KEY和所有UNIQUE KEYS。在UNLOCK TABLEs
之前,调用ALTER TABLE ... ENABLE KEYS
以便线性重建所有非唯一索引。
恕我直言,此操作未编码到InnoDB存储引擎中,因为非唯一索引中的所有键都带有来自gen_clust_index(也称为聚簇索引)的主键条目。这将是一个非常昂贵的操作,因为构建一个非唯一索引需要O(n log n)运行时间来检索每个唯一键以附加到非唯一键。
鉴于此,发布有关在InnoDB表上尝试DISABLE KEYS/ENABLE KEYS
的警告比为涉及非MyISAM存储引擎的任何特殊情况编写mysqldump的异常要容易得多。
答案 2 :(得分:8)
为了降低重新计算索引的成本,您应该使用DATA INFILE或使用Mysql Multi Row Inserts插入数据,例如
INSERT INTO tbl_name(a,b,c)VALUES(1,2,3),(4,5,6),(7,8,9);
- >所以用一个语句插入几行。
一个语句可以插入多少行取决于max_allowed_packet mysql设置。
答案 3 :(得分:3)
有点晚了,但是...无论如何...忘记了这里的所有答案,不要禁用索引,没有办法,只需将它们删除ALTER TABLE表名DROP INDEX whatever
,批量插入数据,然后是ALTER TABLE表名ADD INDEX whatever
(whatever
);重新创建索引的时间是带有索引的批量插入的1%,例如400000行使用索引需要10分钟,而没有索引则需要2秒...,欢呼...