MySQL不会更新information_schema,除非我手动运行ANALYZE TABLE`myTable`

时间:2018-12-19 16:17:52

标签: mysql innodb information-schema mysql-8.0

我需要获取表(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 Server 8.0.13 X64。

2 个答案:

答案 0 :(得分:3)

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

A: 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

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

除了这些变量的设置,或者是通过手动执行ANALYZE TABLE来强制收集统计信息之外,我认为该问题没有解决方法。

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


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

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

让我感到困惑的是为什么我们需要检索此特定信息。我们将用它做什么?

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

如果我们使用ANALYZE TABLE刷新统计信息,那么与随后的SELECT之间还有一段很短的时间...另一个会话可能会进入另一个INSERT,以便从收集统计信息中获取的值在检索时可能已经“过时”。

答案 1 :(得分:2)

SELECT * FROM tbl ORDER BY insert_datetime DESC LIMIT 1;

将从“最新”插入行中获取所有数据。无需处理AUTO_INCREMENT,不需要使用子查询,不需要ANALYZE,不需要information_schema,一旦拥有id后就不需要进行额外提取,等等。

是的,您确实需要在用于确定什么是“最新”的列上建立索引。是的,可以使用id ,但不能使用。 AUTO_INCREMENT的值保证是唯一的,但没有其他