首页 > 解决方案 > MySQL 不更新 information_schema,除非我手动运行 ANALYZE TABLE `myTable`

问题描述

我需要获取表(InnoDB)的最后一个 id(主键),为此我执行以下查询:

SELECT (SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'mySchema' AND `TABLE_NAME` = 'myTable') - 1;

它返回错误的 AUTO_INCREMENT。问题是 information_schema 的 TABLES 表没有用当前值更新,除非我运行以下查询:

ANALYZE TABLE `myTable`;

为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?
运行 MySQL 服务器 8.0.13 X64。

标签: mysqlinnodbinformation-schemamysql-8.0

解决方案


问:为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?

答: InnoDB 将 auto_increment 值保存在内存中,并且不会将其持久化到磁盘。

元数据查询(例如SHOW TABLE STATUS)的行为受innodb_stats_on_metadatainnodb_stats_persistent变量的设置影响。

https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_stats_on_metadata

每次查询元数据时都强制执行 ANALYZE 可能会降低性能。

除了这些变量的设置,或者通过手动执行来强制收集统计信息之外ANALYZE TABLE,我认为这个问题没有“修复”。

(我认为这主要是因为我不认为这是一个需要解决的问题。)


要获取表中 auto_increment 列的最大值,规范模式是:

 SELECT MAX(`ai_col`) FROM `myschema`.`mytable`

令我困惑的是为什么我们需要检索这条特定的信息。我们要用它做什么?

当然,我们不会在应用程序代码中使用它来确定分配给我们刚刚插入的行的值。不能保证最大值不是来自其他会话插入的行。我们有LAST_INSERT_ID()机制来检索我们会话刚刚插入的行的值。

如果我们使用ANALYZE TABLE刷新统计信息,那么在这和后续之间还有一小段时间SELECT......另一个会话可能会滑入另一个会话,INSERT因此我们从收集统计信息中获得的值可能在我们之前“过时”取回它。


推荐阅读