如何在MySQL innoDB中重建索引并更新统计信息?

Tom*_*bes 39 mysql innodb

我有使用MS SQL服务器的经验,可以更新统计信息重建索引.我在MySQL innoDB中找不到这样的选项,有这样的选择吗?如果没有,MySQL数据库如何创建执行计划?MySQL是否更新了每个UPDATE和INSERT的索引和统计信息?

fan*_*nts 52

这是完成的

ANALYZE TABLE table_name;
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多相关信息.

ANALYZE TABLE分析并存储表的密钥分发.在分析过程中,表被锁定,具有MyISAM,BDB和InnoDB的读锁定.此语句适用于MyISAM,BDB,InnoDB和NDB表.

  • 不知道这如何成为公认的答案。它不会重建索引,并且 mysql 已知存在随着时间的推移而降低索引性能的问题。遗憾的是,由于性能低下,OPTIMIZE 表通常不是解决方案 (3认同)
  • 对于MyISAM,它涉及全表扫描; 可能很慢.对于InnoDB,它是一些快速探测器. (2认同)
  • 分析表不会重建索引。如果索引有问题,我认为需要更换。 (2认同)

Ric*_*mes 26

为什么?几乎从不需要更新统计数据.甚至更少需要重建索引.

OPTIMIZE TABLE tbl;将重建索引并做ANALYZE; 这需要时间.

ANALYZE TABLE tbl;InnoDB快速重建统计数据.使用5.6.6甚至更少需要.

  • 我不同意这个答案.当浏览一个大约300k行的旧表时,我更新了索引中的几列,索引仍包含更新前的旧值.我删除了索引并重新创建它,然后它工作正常.MySQL 5.7.10 (11认同)
  • (我正在修改我的立场.)InnoDB的`FULLTEXT`似乎是MySQL中唯一一个重建_may_提供了一些改进的索引. (3认同)
  • @Adergaard-您如何“知道”索引仍然包含旧值?(这可能会导致错误报告。) (2认同)
  • 可能很少需要它,因为许多数据库的数据量有限,变化不那么多,但是如果您有一个非常活跃的大型数据库,并且其中包含大量的插入,更新和删除操作,那么使用夜间优化可以提高性能,在优化前后的复杂选择中,因素的数量级大于10。 (2认同)

bbr*_*own 8

您也可以使用提供的CLI工具mysqlcheck来运行优化。它有很多开关,但最基本的就是您只需输入数据库,用户名和密码。

将其添加到cron或Windows Scheduler可以使此过程自动化。(MariaDB基本上是一样的。)

  • 要对数据库的所有表执行优化:mysqlcheck yourdatabase -p --optimize (4认同)

Joh*_*ohn 6

迄今为止(mysql 8.0.18)在mysql内部没有合适的函数来重新创建索引。
由于 mysql 8.0 myisam 正在慢慢进入弃用状态,innodb 是当前的主要存储引擎。
在大多数实际情况下,innodb 是最佳选择,它应该保持索引正常工作。
在大多数实际情况下,innodb 也做得很好,您不需要重新创建索引。几乎总是。

当涉及具有数百 GB 数据和行的大型表和大量写入情况时,索引可能会降低性能。
在我的个人情况下,我看到性能从使用二级索引的 count(*) 的约 15 分钟下降到 2 个月后以线性时间增加写入表的 4300 分钟。
重新创建索引后,性能又回到了 15 分钟。

迄今为止,我们有两种选择来做到这一点:
1) OPTIMIZE TABLE (或 ALTER TABLE)
Innodb 不支持优化,因此在这两种情况下,整个表都将被读取并重新创建。
这意味着您需要临时文件的存储空间并依赖于表很多时间(我有优化需要一周才能完成的情况)。这将压缩数据并重建所有索引。
尽管没有得到官方推荐,但我强烈推荐在大小不超过 100GB 的大量写入表上使用 OPTIMIZE 过程。

2) ALTER TABLE DROP KEY -> ALTER TABLE ADD KEY
您按名称手动删除密钥,然后再次手动创建。在生产环境中,您首先要创建它,然后删除旧版本。
好处:这可能比优化快得多。缺点:您需要手动创建语法。
“SHOW CREATE TABLE”可用于快速查看哪些索引可用以及它们是如何调用的。

附录:
1) 要更新统计信息,您可以使用已经提到的“分析表”。
2) 如果您在写大量服务器上遇到性能下降,您可能需要重新启动 mysql。当前的 mysql (8.0) 中有几个错误可能会导致显着的速度减慢,而不会显示在错误日志中。最终,这些减速会导致服务器崩溃,但可能需要数周甚至数月的时间来建立崩溃,在此过程中,服务器的响应速度越来越慢。
3) 如果您希望重新创建一个需要数周才能完成或由于内部数据完整性问题在数小时后失败的大表,您应该执行 CREATE TABLE LIKE, INSERT INTO SELECT *。然后“原子重命名”表。
4) 如果 INSERT INTO SELECT * 需要几个小时到几天才能在巨大的表上完成,您可以使用多线程方法将过程加快大约 20-30 倍。您将表“分区”为多个块并并行 INSERT INTO SELECT *。