Mysql 为什么information_schema.tables对行数给出了如此不稳定的答案?

Mysql 为什么information_schema.tables对行数给出了如此不稳定的答案?,mysql,information-schema,Mysql,Information Schema,我在使用MySQL 5.5时遇到了一个奇怪的问题。我想收集关于桌子大小的统计数据。因此,我提出了以下问题: SELECT table_name AS name, data_length, index_length, table_rows, avg_row_length FROM information_schema.TABLES WHERE table_schema = "<MySchema>" AND table_name in (<Table names I'm int

我在使用MySQL 5.5时遇到了一个奇怪的问题。我想收集关于桌子大小的统计数据。因此,我提出了以下问题:

SELECT table_name AS name, data_length, index_length, table_rows, avg_row_length
FROM information_schema.TABLES 
WHERE table_schema = "<MySchema>"
 AND table_name in (<Table names I'm interested in>)
order by table_name;
它一次又一次地给我同样的结果。然而,由于某些原因,信息模式并不是如此。数据库可能有什么问题?或者我只是误解了信息模式中表行的含义?

来自

如果表位于信息架构数据库中,表行列为空

对于InnoDB表,行数只是SQL中使用的粗略估计值 优化。(如果对InnoDB表进行分区,也是如此。)

要更新此估计值,您需要使用
分析表
(请记住,精度取决于
innodb\u stats\u persistent\u sample\u页面

在估计索引列的基数和其他统计信息(如由ANALYZE TABLE计算的统计信息)时要采样的索引页数。增加该值可提高索引统计信息的准确性,从而改进查询执行计划,但在执行InnoDB选项卡的ANALYZE TABLE期间,会增加I/O乐


要获得准确的计数,您需要为INNODB使用
count(*)

您应该使用
information\u schema.INNODB\u SYS\u TABLES stats.NUM\u ROWS
来获得准确的表行计数数据,而不是
information\u schema.TABLES.table\u ROWS

即获取包含行的表列表:

SELECT name 
FROM information_schema.innodb_sys_tablestats 
WHERE name LIKE ("YOUR_DB_SCHEMA_NAME%")
AND num_rows > 0;
在我的例子中,有一个要求是为遗留系统追溯编写集成测试。基于当前的代码库,使用适当的
PDO
transaction
rollback()
是不可能的

对于穷人的事务回滚,我只需选择所有包含数据的表,并在运行测试之前/之后截断。这允许清理种子数据和由于测试插入数据而导致的任何其他脏表

对于MyISAM:


您应该使用lad2025所述的
信息\u模式.表格.表格行
,但我至少可以依赖数据长度和索引长度?我是否正确理解这些列的总和给出了我正在调查的表格的实际大小?@SPIRiT\u 1984这只会给您估计值,因为数据是采样的参见updatedSuppose我不运行分析表。我只想知道当前表的大小。数据长度和索引长度会给我这个摘要信息吗?还是它也只是一个估计值?@SPIRiT_1984这将永远是唯一的估计值(精确的更少或更多)。如果您需要精确的数字计数(*)就是这样。我知道你想比SQL更聪明,以更快地得到结果,但信息模式是一种折衷(速度的准确性)我不是在谈论计数和行数,我是在问表的大小(以字节为单位)-数据长度+总和长度会给我这个信息吗?
INNODB\u SYS\u TABLESTATS
NUM\u rows
也是一个估计值。我自己对这个表的测试表明它返回的数字与
TABLES
table\u ROW相同S.COUNT(*)似乎是innodb唯一可靠的方法。啊,好吧,在我的特殊情况下,我们需要在每次测试前后重复计数,它似乎工作得很好。而information schema.tables仅适用于myisam。在我们的情况下,表行计数的更新似乎有延迟。我想知道是否还有其他原因,这很遗憾,我真的很想验证这个方法,因为它会非常有用。文档中提到,在每次DML操作后,估计值都会更新,如果您得到行数的差异,这可能解释您使用此方法成功的原因。
SELECT name 
FROM information_schema.innodb_sys_tablestats 
WHERE name LIKE ("YOUR_DB_SCHEMA_NAME%")
AND num_rows > 0;