迭代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时都会有这么大的差异?
这只发生在这张桌子上,我检查了几张较大的桌子,每次访问时都显示相同的数字
FYI指望桌子:
mysql> select count(*) from mybigusertable;
+----------+
| count(*) |
+----------+
| 3109320 |
+----------+
1 row in set (4 min 34.00 sec)
几个问题:
答案 0 :(得分:1)
我认为问题源于如何处理InnoDB的表元数据。
InnoDB倾向于使用某种形式的搜索深度近似(由optimizer_search_depth指示),这需要潜入猜测基数的索引。
SET GLOBAL innodb_stats_on_metadata = 0;
这将有助于更快地读取元数据并稳定查询执行计划。
对InnoDB表执行OPTIMIZE TABLE是没用的,因为一旦你这样做以尝试编译索引统计信息,如果innodb_stats_on_metadata在2011年6月仍为1 I wrote about this in the DBA StackExchange,它往往会再次重读。
好的,因为你使用的是MySQL 5.0.77,所以OPTIMIZE TABLE对于InnoDB中的索引统计信息重建来说简直太旧了。
OPTIMIZE TABLE和ANALYZE TABLE仅适用于MyISAM。
答案 1 :(得分:0)
MySQL通过从索引中对随机页面进行采样来确定索引的基数。页面具有不同的记录数和分布。
对于基数没有变化的索引,索引可能适合单个页面,或者页面具有均匀分布(例如,来自优化表)。
如果计数差异很大,您可以考虑优化表格以重新分配记录。这将有助于MySQL选择最佳索引。