MySQL information_schema报告的行数少于count()

时间:2016-10-24 16:25:16

标签: mysql

MySQL count(*)information_schema.TABLES报告的数据完全不同。

mysql> SELECT * FROM information_schema.TABLES WHERE TABLE_NAME = 'my_table'\G
*************************** 1. row ***************************
  TABLE_CATALOG: def
   TABLE_SCHEMA: my_db
     TABLE_NAME: my_table
     TABLE_TYPE: BASE TABLE
         ENGINE: InnoDB
        VERSION: 10
     ROW_FORMAT: Compact
     TABLE_ROWS: 31016698
 AVG_ROW_LENGTH: 399
    DATA_LENGTH: 12378439680
MAX_DATA_LENGTH: 0
   INDEX_LENGTH: 4863262720
      DATA_FREE: 5242880
 AUTO_INCREMENT: NULL
    CREATE_TIME: 2016-06-14 18:54:24
    UPDATE_TIME: NULL
     CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
       CHECKSUM: NULL
 CREATE_OPTIONS: 
  TABLE_COMMENT: 
1 row in set (0.00 sec)
mysql> select count(*) from my_table;
+----------+
| count(*) |
+----------+
| 46406095 |
+----------+
1 row in set (27.45 sec)

请注意,根据information_schemacount() 31,016,698 行,但报告 46,406,095 行......

现在哪一个可以信任?为什么这些统计数据有所不同?

我正在使用 MySQL服务器v5.6.30

1 个答案:

答案 0 :(得分:0)

该元数据中的计数与for(int i = 0; i < tran.size(); i++){ Set<Integer> temp = tran.get(i); 的输出类似,不可信任。它往往超过或超过100倍或更多。

原因是引擎在计算表之前不知道表中有多少行。在负载很重的情况下,您可能会在主键索引上产生很多争用,这会使精确值固定为昂贵的计算。

基于总数据长度除以平均行长度来计算该近似值。除非您的记录长度相同,并且您还没有删除其中的大部分内容,否则它甚至很少接近它应该是什么。

可以真正信任的唯一值是SHOW TABLE STATUS,但该操作可能需要很长时间才能完成,因此请注意。