1

有一个表 tb_tag_article 像

CREATE TABLE `tb_tag_article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag_id` int(16) NOT NULL,
  `article_id` int(16) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `key_tag_id_article_id` (`tag_id`,`article_id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=365944 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

当我这样查询时,结果是5120

SELECT count(*) FROM tb_tag WHERE tag_id = 43

但是当我这样解释查询时

EXPLAIN SELECT count(*) FROM tb_tag WHERE tag_id = 43

检查的行是13634

+------+-------------+----------------+------+-----------------------+-----------------------+---------+-------+-------+-------------+
| id   | select_type | table          | type | possible_keys         | key                   | key_len | ref   | rows  | Extra       |
+------+-------------+----------------+------+-----------------------+-----------------------+---------+-------+-------+-------------+
|    1 | SIMPLE      | tb_tag_article | ref  | key_tag_id_article_id | key_tag_id_article_id | 4       | const | 13634 | Using index |
+------+-------------+----------------+------+-----------------------+-----------------------+---------+-------+-------+-------------+

该查询使用索引,但检查的行数大于实际数据的计数。有什么问题?

4

2 回答 2

0

从 MySQL 参考(http://dev.mysql.com/doc/refman/5.0/en/explain-output.html#explain_rows):

rows 列表示 MySQL 认为它必须检查以执行查询的行数。

对于 InnoDB 表,这个数字是一个估计值,可能并不总是准确的。

也可能是因为它必须分析索引,它会考虑索引中的记录数加上表中的记录数。但这只是一个假设。

此外,在 MySQL 5.1 中似乎存在一个带有 Explain Row 估计的错误,导致该数字严重偏离:http ://bugs.mysql.com/bug.php?id=53761根据您的版本,这可能会解释一些的怪事。

文档的主要内容似乎是用一粒盐树 EXPLAIN rows 列。

于 2014-10-06T14:56:24.460 回答
0

问:有什么问题?

A:看起来没有什么问题。

EXPLAIN 输出中" rows" 列的值是估计值,而不是确切数字。

参考:http ://dev.mysql.com/doc/refman/5.5/en/explain-output.html


为了评估每个可能的访问路径的“成本”,优化器只需要估计,以便比较对索引使用范围扫描操作与对表中所有行进行全扫描的效率。优化器不需要表中总行数的“精确”计数,或者满足谓词的行数。

对于这个简单的查询,MySQL 只考虑几个可能的计划。

而 13684 的估计与行的确切计数相差不远。它相差了 2.5 倍,但 MySQL 提出了正确的执行计划:使用索引,而不是检查表中的每一行。

没有问题。

于 2014-10-06T14:58:11.333 回答