MySQL 不更新 information_schema,除非我手动 运行 分析 TABLE `myTable`
MySQL not updating information_schema, unless I manually run ANALYZE TABLE `myTable`
我需要获取 table (InnoDB) 的最后一个 ID(主键),为此我执行以下查询:
SELECT (SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'mySchema' AND `TABLE_NAME` = 'myTable') - 1;
哪个returns错了AUTO_INCREMENT。问题是 information_schema 的 TABLES table 没有用当前值更新,除非我 运行 以下查询:
ANALYZE TABLE `myTable`;
为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?
运行 MySQL 服务器 8.0.13 X64.
问: 为什么 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
强制收集统计信息外,我认为没有 "fix" 问题。
(我认为这主要是因为我认为这不是需要解决的问题。)
获取table中某auto_increment列的最大值,规范模式为:
SELECT MAX(`ai_col`) FROM `myschema`.`mytable`
令我困惑的是为什么我们需要检索这条特定的信息。我们要用它做什么?
当然,我们不会在应用程序代码中使用它来确定分配给我们刚刚插入的行的值。不能保证最大值不是来自其他会话插入的行。我们有 LAST_INSERT_ID()
机制来检索我们的会话刚刚插入的行的值。
如果我们使用 ANALYZE TABLE
来刷新统计数据,那么在这和随后的 SELECT
之间还有一小段时间...另一个会话可能会插入另一个 INSERT
所以我们从收集统计数据中获得的值在我们检索时可能是 "out of date"。
SELECT * FROM tbl ORDER BY insert_datetime DESC LIMIT 1;
将从 "latest" 插入的行中获取所有数据。不需要处理 AUTO_INCREMENT
,不需要使用子查询,没有 ANALYZE
,没有 information_schema
,一旦有了 id 就没有额外的获取,没有等等
是的,您确实需要在用于确定什么是 "latest" 的列上建立索引。是的,id
可以,但不应该。 AUTO_INCREMENT
值保证是唯一的,但没有 其他值。
我需要获取 table (InnoDB) 的最后一个 ID(主键),为此我执行以下查询:
SELECT (SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'mySchema' AND `TABLE_NAME` = 'myTable') - 1;
哪个returns错了AUTO_INCREMENT。问题是 information_schema 的 TABLES table 没有用当前值更新,除非我 运行 以下查询:
ANALYZE TABLE `myTable`;
为什么 MySQL 不自动更新 information_schema,我该如何解决这个问题?
运行 MySQL 服务器 8.0.13 X64.
问: 为什么 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
强制收集统计信息外,我认为没有 "fix" 问题。
(我认为这主要是因为我认为这不是需要解决的问题。)
获取table中某auto_increment列的最大值,规范模式为:
SELECT MAX(`ai_col`) FROM `myschema`.`mytable`
令我困惑的是为什么我们需要检索这条特定的信息。我们要用它做什么?
当然,我们不会在应用程序代码中使用它来确定分配给我们刚刚插入的行的值。不能保证最大值不是来自其他会话插入的行。我们有 LAST_INSERT_ID()
机制来检索我们的会话刚刚插入的行的值。
如果我们使用 ANALYZE TABLE
来刷新统计数据,那么在这和随后的 SELECT
之间还有一小段时间...另一个会话可能会插入另一个 INSERT
所以我们从收集统计数据中获得的值在我们检索时可能是 "out of date"。
SELECT * FROM tbl ORDER BY insert_datetime DESC LIMIT 1;
将从 "latest" 插入的行中获取所有数据。不需要处理 AUTO_INCREMENT
,不需要使用子查询,没有 ANALYZE
,没有 information_schema
,一旦有了 id 就没有额外的获取,没有等等
是的,您确实需要在用于确定什么是 "latest" 的列上建立索引。是的,id
可以,但不应该。 AUTO_INCREMENT
值保证是唯一的,但没有 其他值。