为什么innodb的SHOW TABLE STATUS如此不可靠?

car*_*pii 15 mysql innodb

我知道你不应该依赖InnoDB的SHOW TABLE STATUS返回的值.特别是行数和平均数据长度.

但我想也许这是在某个时刻采取的准确值,然后innodb只会在ANALYZE表或其他一些不常见的事件中刷新它.

相反,我看到的是我可以在5秒内在同一个桌面上运行SHOW TABLE STATUS 5次,并且每次都获得完全不同的数字(尽管表中没有任何插入/删除活动)

这些价值实际上来自哪里?它们在innodb中是否只是腐败?

ven*_*zen 23

MySQL 5.1官方文档承认InnoDB没有提供准确的统计数据SHOW TABLE STATUS.虽然MYISAM表专门保留元数据的内部缓存,例如行数等,但InnoDB引擎将表数据和索引存储在*/var/lib/mysql/ibdata中**

InnoDB没有权宜的索引文件,可以快速查询行号.

SHOW TABLE STATUS由于InnoDB通过对表数据的范围(在*/var/lib/mysql/ibdata**中)进行采样来动态估计"行"值,然后推断出大致的行数,因此报告了不一致的表行数.因此,InnoDB文档在使用时确认行数不准确率高达50%SHOW TABLE STATUS

MySQL文档建议使用MySQL查询缓存来获得一致的行号查询,但文档没有指定如何.下面简要说明如何做到这一点.

首先,检查是否启用了查询缓存:

mysql> SHOW VARIABLES LIKE 'have_query_cache';
Run Code Online (Sandbox Code Playgroud)

如果have_query_cache的值为NO,则通过将以下行添加到/etc/my.cnf启用查询缓存,然后重新启动mysqld.

have_query_cache=1    # added 2017 08 24 wh
query_cache_size  = 1048576
query_cache_type  = 1
query_cache_limit = 1048576
Run Code Online (Sandbox Code Playgroud)

(有关更多信息,请参阅http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)

使用查询缓存的内容

mysql> SHOW STATUS LIKE 'Qcache%';
Run Code Online (Sandbox Code Playgroud)

现在SQL_CALC_FOUND_ROWSSELECT查询中使用该语句:

SELECT SQL_CALC_FOUND_ROWS COUNT(*) FROM my_innodb_table
Run Code Online (Sandbox Code Playgroud)

SQL_CALC_FOUND_ROWS将尝试从缓存中读取,如果找不到此查询,则对指定的表执行查询,然后将表行数提交到查询缓存.上述查询的其他执行(或其他'cachable' SELECT语句 - 见下文)将查询缓存并返回正确的结果.

随后的"可SELECTLIMIT缓存" 查询 - 即使它们是结果 - 将查询查询缓存并允许您获取(仅一次性)总表行数

SELECT FOUND_ROWS();
Run Code Online (Sandbox Code Playgroud)

它返回先前缓存的查询的正确表行总数.