首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL是否更新所有插入的索引?我可以在每次插入x之后更新它吗?

MySQL是否更新所有插入的索引?我可以在每次插入x之后更新它吗?
EN

Stack Overflow用户
提问于 2014-05-02 19:13:49
回答 4查看 5.8K关注 0票数 15

关于MySQL索引,我有几个相关的问题:

  1. MySQL是否每次插入某项内容时都更新索引?
  2. 当MySQL由于插入而更新索引时,它是否重新生成整个索引?
  3. 有没有办法让MySQL在每次插入x之后更新索引?

我的应用程序中有很多插入,我担心MySQL在每次插入之后都会重新构建索引。数据不必是实时的,所以我可以在特定数量的插入之后更新索引(如果可能的话)。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-02 19:41:38

MySQL可能已经在做您所描述的事情了,尽可能多。

对于InnoDB (应该是默认的MySQL存储引擎),立即插入和更新并删除更改主键或唯一键索引。但是,他们从不重建整个索引,而是向这些索引中添加新值(或从这些索引中提取值)。

对于非唯一索引,InnoDB执行变化缓冲。也就是说,它将对更改进行排队,这些更改将合并到后面的后台索引中。它甚至将合并更改,以便更有效地对索引进行物理更新。

您不需要做任何事情来启用这个特性,因为默认情况下它是启用的。MySQL 5.1只为INSERT更改缓冲。此外,MySQL 5.5和更高版本还会更改UPDATEDELETE的缓冲。

如果需要,可以禁用此功能(例如,如果使用SSD,避免随机I/O并不那么重要,您可能希望确保队列中的更改不会累积)。通常,您应该保持启用该功能。

票数 15
EN

Stack Overflow用户

发布于 2014-05-02 19:22:48

MySQL不会在每次插入后“重建”索引。MySQL将一行或多行插入到现有索引中。

MySQL有很多不寻常的选择,我不知道所有的选择。如果有这样一种选择,我会感到惊讶:“哦,让表上的指数与表中的数据不同步。”听起来不合理。

如果您有很多插入,最好的策略是在一个语句中执行插入。而不是:

代码语言:javascript
运行
复制
insert into t(...)
    select . . .
    from t2
    where id = id1;

做:

代码语言:javascript
运行
复制
insert into t(...)
    select . . .
    from t2
    where id in (id1, id2, . . .)

它的一个扩展是插入到临时表中。然后立即将临时表加载到大表中:

代码语言:javascript
运行
复制
insert into t(...)
    select ...
    from temptable;

最后,有时会更快地删除索引,执行大插入(在一个或多个步骤中),然后重新创建索引。

注意:如果删除唯一索引,也会删除唯一约束。如果您使用的是on duplicate key update,这一点很重要,因为它需要一个辅助索引来查找重复的键(主键除外)。

票数 4
EN

Stack Overflow用户

发布于 2014-05-02 20:50:08

当MySQL由于插入而更新索引时,它是否重新生成整个索引?

不,MySQL不会“重建”每次插入的索引。

MySQL的默认页面大小是16K。它以1MB的增量(称为区段)分配这些页面。

当第一次创建一个表(重新生成索引)时,页面将被填满15/16,为一些随机插入留下空间。如果索引条目每个为500个字节(主键大小+聚集索引的行数据),则在必须拆分页之前为插入两个新行留出空间。

当MySQL需要在整个页面上插入一行时,页面必须被分割。MySQL将添加一个新页面,并将一半的页面数据移动到新页面。

在一个页面中,记录可能实际上并不是按物理顺序排列的。它们会按插入顺序排列。它们是通过一种链接列表的形式按顺序链接的。因此,即使是随机插入也不会导致数据被物理地重新排序。在需要拆分页面的情况下,数据不会被移动。

5月份随机插入后,您的页面将从1/2满到满。

所有这些工作都会影响插入性能,因为索引必须与每个插入一起更新。此外,包含半整页的索引会对阅读性能产生负面影响。

现在,如果您按索引顺序插入行,那么MySQL只需将行添加到页面的末尾,将它们填满15/16,并在页面时添加一个区段。更不用说性能损失了,因为没有分页,因此不涉及数据的移动,更不用说几乎整页的读取性能好处了。

因此,虽然在更新插入索引时需要进行一些维护,但MySQL并不是在“重建”每个插入的索引。另外,请看比尔·卡温的关于更改缓冲的注意事项,这可能会影响到你。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23435361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档