为啥“解释”返回的行不等于count()?

Posted

技术标签:

【中文标题】为啥“解释”返回的行不等于count()?【英文标题】:Why the rows returns by "explain" is not equal to count()?为什么“解释”返回的行不等于count()? 【发布时间】:2009-06-24 10:07:38 【问题描述】:
    mysql> select count(*) from table where relation_title='xxxxxxxxx';
+----------+
| count(*) |
+----------+
|  1291958 |
+----------+

mysql> explain select *  from table where relation_title='xxxxxxxxx';
+----+-------------+---------+-
| id | select_type | rows    |
+----+-------------+---------+-
|  1 | SIMPLE      | 1274785 | 
+----+-------------+---------+-

我认为“解释 select * from table where relation_title='xxxxxxxxx';”按索引返回relation_title='xxxxxxxxx' 的行。但它比真正的数字要小。

【问题讨论】:

EXPLAIN and COUNT returning two different values的可能重复 【参考方案1】:

它显示了它运行了多少行以获得您的结果。

错误数据的原因是 EXPLAIN 不准确,它根据存储的有关您的表的信息来猜测您的数据。

这是非常有用的信息,例如,在对许多表进行 JOINS 时,并且您希望确保您没有针对您拥有的每一行的一行信息运行整个连接表。

这是对 608 行表的测试。

SELECT COUNT(id) FROM table WHERE user_id = 1

结果:

COUNT(id)
512

这里是解释

EXPLAIN SELECT COUNT(id) FROM table WHERE user_id = 1

结果:

id  rows
1   608

【讨论】:

你是对的。但我的条件是解释小于 COUNT() 而且,我已经优化了表格。【参考方案2】:

EXPLAIN 查询将使用 INFORMATION_SCHEMA 表中提供的值,其中包含对 innodb 表行数的粗略估计 - 请参阅 mysql docs on INFORMATION_SCHEMA.TABLES 中的注释部分。

【讨论】:

【参考方案3】:

执行ANALYZE TABLE table_name; - 它将更新 EXPLAIN 使用的统计信息,您将获得正确的数字。例如:当表中根本没有数据时,EXPLAIN 会提示该表为空,并优化查询以首先根据该表进行过滤(因为它不会从磁盘、内存等读取任何内容)。那么当你不执行ANALYZE TABLE table_name;会加载数据时,优化器仍然提示表还是空的,并且没有使用最优的执行计划进行查询。 EXPLAIN 的行为方式相同 - 它不查找表中的当前行数,它查找由 ANALYZE TABLE table name 生成的统计信息(在某些情况下会自动执行 - 例如,表中行数的 1/16 已更改)。

【讨论】:

【参考方案4】:

OP的问题是有效的,但从答案来看,我认为对explain的rows列实际上告诉我们的内容存在误解。

the mysql documentation for explain rows 状态:

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

所以COUNT(*) 告诉您的内容和解释行告诉您的内容是两件不同的事情,可能会导致相同的数字,但它们不是相同的信息。

第一个是与正在运行的查询匹配的所有行的计数。第二个是对运行查询需要检查的所有行的估计。

所以当我跑步时

SELECT COUNT(id) FROM table WHERE user_id = 1

我得到了 user_id = 1 的行数。

当我跑步时

EXPLAIN SELECT COUNT(id) FROM table WHERE user_id = 1

rows 列包含 mysql 需要经过的所有行才能给你答案。在这种情况下,这就是整个表格。

【讨论】:

以上是关于为啥“解释”返回的行不等于count()?的主要内容,如果未能解决你的问题,请参考以下文章

为啥排序行会减少解释中的行数?

HIVE select count(*) 非 null 返回高于 select count(*) 的值

组上的 MySQL COUNT() 返回错误的行数

为啥 count(false) 返回 1?

为啥变量_count总是返回-1?

hive聚合函数