如何在innodb中禁用索引

fan*_*yna 31 mysql indexing innodb

我试图通过临时禁用其索引来加速InnoDB表中的批量插入:

ALTER TABLE mytable DISABLE KEYS;
Run Code Online (Sandbox Code Playgroud)

但它发出警告:

+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytable' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

我们如何禁用索引?

在进行批量插入时,有哪些替代方法可以避免使用索引?

我们怎样才能加快这个过程?

lur*_*low 31

你试过以下吗?

    SET autocommit=0; 
    SET unique_checks=0; 
    SET foreign_key_checks=0;
Run Code Online (Sandbox Code Playgroud)

来自MySQL参考资料https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

请参见" 批量数据加载提示 "一节


Rol*_*DBA 29

你有一个很好的理由不能DISABLE KEYS在InnoDB表上执行; InnoDB不是为了使用而设计的,而MyISAM则是.

实际上,这是当你重新加载mysqldump时会发生的事情:

您将看到一个CREATE TABLE用于写入锁定的MyISAM表.

在运行所有批量插入之前,将ALTER TABLE ... DISABLE KEYS完成调用.

这样做是关闭MyISAM表中的二级索引.

然后,完成批量插入.在执行此操作时,将禁用MyISAM表中的PRIMARY KEY和所有UNIQUE KEYS.在此之前UNLOCK TABLEs,调用ALTER TABLE ... ENABLE KEYS是为了线性重建所有非唯一索引.

恕我直言,此操作未编码到InnoDB存储引擎中,因为非唯一索引中的所有键都带有来自gen_clust_index(也称为聚簇索引)的主键条目.这将是一个非常昂贵的操作,因为构建非唯一索引将需要O(n log n)运行时间来检索每个唯一键以附加到非唯一键.

有鉴于此,发布关于尝试DISABLE KEYS/ENABLE KEYS使用InnoDB表的警告比为涉及非MyISAM存储引擎的任何特殊情况编写mysqldump的异常要容易得多.

  • 感谢您的解释,但问题仍然存在:如何在上传数据时避免使用索引,以减少导入时间.谢谢. (3认同)
  • 我经常构建非常大的`innodb`表,其中包含大量索引(数百千兆字节/ 10多个不同的索引).当我"插入"没有索引的表时,创建时间大大减少.显然,"巨大"在很大程度上取决于表的最终大小,索引的数量和类型,数据元素的类型等.我通常只使用主键构建表(如果只是加载则不需要)已经具有主键ID的数据,然后在最后构建索引.您可能没有注意到5MM行和1.5GB的差异,但随着您的表增长,您将会. (2认同)

sta*_*abm 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_pa​​cket mysql设置.

  • 看我之前的评论.我特意没有说在一个声明中做事.<sarcasm>如果您的服务器具有无限量的内存 - 您可以使用无限大/长/大语句</ sarcasm> (3认同)
  • 你确定吗?那么您是在告诉我们使用**单个**插入语句插入一百万行吗? (2认同)
  • 我不是告诉你用一条语句插入“所有数据”,而是一次插入几行。在我的应用程序中,我每次插入使用 500-1000 行,没有出现任何问题。它主要取决于行数和每行插入的数据量。 (2认同)

小智 7

有点晚了,但是...无论如何...忘记这里的所有答案,不要禁用索引,没有办法,只需将它们删除ALTER TABLE表名DROP INDEX whatever,批量插入数据,然后ALTER TABLE表名ADD INDEX whateverwhatever) ; 重新创建索引的时间是上面带有索引的大容量插入的1%,例如400000行使用索引需要10分钟,而没有索引则需要2秒...,欢呼...

  • 请记住,删除索引后,*不会强制执行对键的任何约束*,因此后续的“CREATE INDEX”很可能会失败。 (2认同)