Mysql 显示表状态的疯狂基数计数

Mysql 显示表状态的疯狂基数计数,mysql,database,optimization,query-optimization,cardinality,Mysql,Database,Optimization,Query Optimization,Cardinality,迭代1: mysql> show table status LIKE "mybigusertable"; +-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+----

迭代1:

mysql> show table status LIKE "mybigusertable";
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+
| Name            | Engine | Version | Row_format | Rows    | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment                  |
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+
| mybigusertable | InnoDB |      10 | Compact    | 3089655 |           1686 |  5209325568 |               0 |    797671424 |         0 |        3154997 | 2011-12-04 03:46:43 | NULL        | NULL       | utf8_unicode_ci |     NULL |                | InnoDB free: 13775872 kB | 
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+

mysql> show index from mybigusertable;
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table           | Non_unique | Key_name        | Seq_in_index | Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| mybigusertable |          0 | PRIMARY         |            1 | someid         | A         |     3402091 |     NULL | NULL   |      | BTREE    
迭代2

mysql> show index from mybigusertable;
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table           | Non_unique | Key_name        | Seq_in_index | Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| mybigusertable |          0 | PRIMARY         |            1 | someid         | A         |     2811954 |     NULL | NULL   |      | BTREE    
上述两次之间的时间不到5秒。为什么每次调用show index时都会有如此巨大的差异

这种情况只发生在这个表上,我检查了几个较大的表,它们每次被访问时都显示相同的数字

供参考,请参考表格:

mysql> select count(*) from mybigusertable;
+----------+
| count(*) |
+----------+
|  3109320 | 
+----------+
1 row in set (4 min 34.00 sec)
几个问题:

  • 为什么基数变化如此之大,这真的很重要吗
  • 有多重要?它会使查询更快吗
    MySQL通过从索引中随机抽取页面来确定索引的基数。页面具有不同的记录计数和分布

    对于基数不变的索引,很可能索引适合单个页面,或者页面具有均匀分布(例如,来自优化表)


    如果计数变化很大,可以考虑优化表来重新分配记录。这将帮助MySQL选择最佳索引。

    我认为问题源于InnoDB如何处理表元数据

    InnoDB倾向于使用某种形式的搜索深度近似(由指定),这需要深入到索引中猜测基数

    试着出发

    这将有助于更快地读取元数据并稳定查询执行计划

    美国东部时间2012-03-06 11:55更新 对InnoDB表执行OPTIMIZE TABLE是没有用的,因为一旦您尝试编译索引统计信息,如果InnoDB_stats_on_metadata仍然为1,它就会再次被读取。回到2011年6月

    更新2012-03-06 11:59美国东部时间 好的,因为您使用的是MySQL 5.0.77,所以OPTIMIZE TABLE对于InnoDB中的索引统计数据的重新生成毫无用处


    优化表和分析表仅适用于MyISAM。

    我们至少有一年没有优化此表(约1.5mil+条记录)。唯一的问题是,该应用程序是高可用性应用程序,严重停机是危险的。优化过程中的宕机是可以的,只是不想让事情变得更慢,因为我在过去看到,优化实际上减慢了许多查询的速度,只要数字在同一个球场上,或者您不依赖MySQL来选择最佳索引(在两个或多个具有相似基数的索引之间),那就没什么好担心的了。嗯,所以运行优化或分析对我没有任何好处!InnoDB有类似的功能吗?查询速度非常慢,EXPLAIN显示了非常好的数字,需要扫描几百行等等,但是运行相同的查询是一场噩梦。在3+密耳行表上进行简单计数需要5分钟。
    SET GLOBAL innodb_stats_on_metadata = 0;