我使用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;
然而,当我在几秒钟内多次运行此查询时,我注意到一些奇怪的事情。 data_length和index_length在所有查询中实际上保持相同(或者稍微改变一下,因为在客户执行脚本期间有一些写入)。
然而,table_rows每次给出一个非常不同的答案。例如,第一个查询为表A提供了大约10000行,第二个查询表示它大约有20000行,依此类推。但是,当我像这样运行查询时:
select count(*) from TableA;
它一次又一次地给我相同的结果。但是,由于某种原因,不是信息模式。数据库有什么问题?或者我可能只是误解了information_schema中table_rows的含义?
答案 0 :(得分:3)
如果表位于INFORMATION_SCHEMA数据库中,则 TABLE_ROWS 列为NULL。
对于InnoDB表,SQL中使用的行数仅粗略估计 优化。 (如果对InnoDB表进行分区,也是如此。)
要更新此估算值,您需要使用ANALYZE TABLE
(请注意,innodb_stats_persistent_sample_page
上的准确度依赖于:
<强>
innodb_stats_persistent_sample_pages
强>在估算索引列的基数和其他统计信息时要采样的索引页数,例如由ANALYZE TABLE计算的那些。增加值可以提高索引统计信息的准确性,这可以改善查询执行计划,但代价是在执行InnoDB表的ANALYZE TABLE期间增加了I / O
要获得准确计数,您需要使用COUNT(*)
。
答案 1 :(得分:-1)
FOR INNODB:
您应该使用information_schema.INNODB_SYS_TABLESTATS.NUM_ROWS
来获取准确的表格行计数数据,而不是information_schema.TABLES.TABLE_ROWS
。
即获取包含行的表列表:
SELECT name
FROM information_schema.innodb_sys_tablestats
WHERE name LIKE ("YOUR_DB_SCHEMA_NAME%")
AND num_rows > 0;
就我而言,需要追溯性地为遗留系统编写集成测试。根据当前的代码库,使用正确的PDO
交易rollback()
是不可能的......
对于穷人的事务回滚,我只需选择包含数据的所有表并在运行测试之前/之后截断。这允许由于测试插入数据而清理种子数据和任何其他脏表。
FOR MyISAM:
你应该按照lad2025的说明使用information_schema.TABLES.TABLE_ROWS