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