Yan*_*rin 9 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;
Run Code Online (Sandbox Code Playgroud)
它返回错误的 AUTO_INCREMENT。问题是 information_schema 的 TABLES 表未使用当前值更新,除非我运行以下查询:
ANALYZE TABLE `myTable`;
Run Code Online (Sandbox Code Playgroud)
为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?
运行 MySQL 服务器 8.0.13 X64。
spe*_*593 10
问:为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?
A: InnoDB 将 auto_increment 值保存在内存中,并且不会将其持久化到磁盘。
元数据查询(例如SHOW TABLE STATUS)的行为受innodb_stats_on_metadata和innodb_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`
Run Code Online (Sandbox Code Playgroud)
让我困惑的是为什么我们需要检索这条特定的信息。我们要用它做什么?
当然,我们不会在应用程序代码中使用它来确定分配给我们刚刚插入的行的值。不能保证最高值不是来自其他会话插入的行。我们有LAST_INSERT_ID()机制来检索我们的会话刚刚插入的行的值。
如果我们使用ANALYZE TABLE刷新统计数据,那么在此和后续之间还有一小段时间SELECT......另一个会话可能会滑入另一个会话,INSERT因此我们从收集统计信息中获得的值可能在我们之前“过时”取回它。