如何在MySQL innoDB中重建索引和更新统计数据?

如何在MySQL innoDB中重建索引和更新统计数据?,mysql,innodb,Mysql,Innodb,我有使用MS SQL server的经验,在这些经验中,可以使用和。我在MySQL innoDB中找不到这样的选项,有这样的选项吗?如果没有,MySQL数据库如何创建执行计划?MySQL是否会在每次更新和插入时更新索引和统计信息?这是通过 ANALYZE TABLE table_name; 阅读更多关于它的信息 分析表分析并存储表的密钥分布。在分析过程中,使用MyISAM、BDB和InnoDB的读锁锁定该表。此语句适用于MyISAM、BDB、InnoDB和NDB表 为什么??几乎不需要更新统计

我有使用MS SQL server的经验,在这些经验中,可以使用和。我在MySQL innoDB中找不到这样的选项,有这样的选项吗?如果没有,MySQL数据库如何创建执行计划?MySQL是否会在每次更新和插入时更新索引和统计信息?

这是通过

ANALYZE TABLE table_name;
阅读更多关于它的信息

分析表分析并存储表的密钥分布。在分析过程中,使用MyISAM、BDB和InnoDB的读锁锁定该表。此语句适用于MyISAM、BDB、InnoDB和NDB表


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

优化表tbl
将重建索引并进行
分析
;这需要时间


分析表tbl
对于InnoDB来说重建统计数据很快。对于5.6.6,甚至不需要它。

您还可以使用提供的CLI工具
mysqlcheck
来运行优化。它有一个密码,但在最基本的情况下,您只需传入数据库、用户名和密码

将其添加到cron或Windows调度程序中可以使其成为一个新的应用程序。(但基本上是一样的。)

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

当涉及到包含数百GB数据行和大量写入的大型表时,情况会发生变化,索引的性能可能会降低。
在我个人的例子中,我看到使用二级索引的计数(*)的性能从大约15分钟下降到4300分钟,在2个月的时间线性增加的情况下写入表中。
重新创建索引后,性能将恢复到15分钟

到目前为止,我们有两种选择:
1)优化表格(或更改表格)
Innodb不支持优化,因此在这两种情况下都会读取并重新创建整个表。
这意味着您需要存储临时文件,这取决于表的时间(我有过优化需要一周才能完成的情况)。 这将压缩数据并重建所有索引。
尽管没有得到官方的推荐,但我还是强烈建议对大小高达100GB的写容量较大的表执行优化过程

2)更改表格拖放键->更改表格添加键 手动按名称删除密钥,然后再次手动创建。在生产环境中,您需要先创建它,然后删除旧版本。
好处:这比优化要快得多。缺点:您需要手动创建语法。
“showcreatetable”可用于快速查看哪些索引可用以及如何调用它们

附录:
1) 要更新统计信息,您可以使用前面提到的“分析表”。
2) 如果您在写操作繁重的服务器上遇到性能下降,您可能需要重新启动mysql。在当前的mysql(8.0)中,有几个bug可能会导致显著的速度减慢,而不会出现在错误日志中。最终,这些减速会导致服务器崩溃,但可能需要数周甚至数月的时间才能恢复到崩溃状态,在此过程中,服务器的响应速度会越来越慢。
3) 如果您希望重新创建一个需要数周才能完成的大型表,或者由于内部数据完整性问题而在数小时后失败,那么您应该创建一个类似INSERT INTO SELECT*的表。然后对表进行“原子重命名”。

4) 如果INSERT INTO SELECT*需要数小时到数天才能在大型表上完成,则可以使用多线程方法将过程加快20-30倍。您可以将表“分区”为块并并行插入SELECT*中。

对于基本清理和重新分析,您可以运行“优化表…”,它将压缩索引中的开销并运行ANALYZE table,但它不会对它们进行重新排序,使它们尽可能小而高效

但是,如果希望完全重建索引以获得最佳性能,可以:

  • 删除/重新添加索引(显然)
  • 转储/重新加载表
  • 使用相同的存储引擎更改表和“更改”
  • 修复表(仅适用于MyISAM、存档和CSV)

  • 如果您对字段(即索引的一部分)执行ALTER TABLE并更改其类型,那么它也将完全重建相关索引。

    Perfect,这正是我所寻找的。对于MyISAM,它涉及到完整的表扫描;可能很慢。对于InnoDB来说,这只是一些快速探测。Analyze tabe不会重建索引。如果索引有问题,我想需要替换。不知道这怎么可能是公认的答案。这并不是重建索引,mysql也知道随着时间的推移会出现索引性能下降的问题。可悲的是,优化表往往是没有解决方案,因为它的低performance@fancyPants你错了。您的答案是“分析表”是重建索引的解决方案。事实上这是不对的,不应该是答案。innodb上的OPTIMIZE表进行了完整的重新创建,其中包括一个紧凑的索引变体,它可以将某些边界情况下的索引性能提高数千倍。说到mysql 8.0.16,事情可能会随着时间的推移而改变。我不同意这个答案。在浏览一个大约300k行的旧表时,我更新了索引中的两列,索引仍然包含更新之前的旧值。我删除了索引并重新创建了它,然后它工作得很好。MySQL 5.7。10@Adergaard-您如何“知道”索引仍然包含旧值?(这可能导致错误报告。)如@Adergaard,