【问题标题】:Why is count(*) slow, when explain knows the answer?当解释知道答案时,为什么 count(*) 慢?
【发布时间】:2020-02-14 09:43:42
【问题描述】:

我正在使用 MySQL InnoDB。该表有 1000 万条记录。我正在尝试执行以下查询,但执行时间过长。

SELECT COUNT(*) FROM abc_test WHERE id = ? AND parent_id IS NULL AND user_status IN (?,?,?,?);

有人可以帮忙吗?以下是相同的详细信息。

  1. 云:AWS
  2. 数据库:MySQL RDS(r3.2xlarge)
  3. 版本:5.6.34

表结构(共 50 列)

  • id int(11)
  • parent_id int(11)
  • user_status tinyint(4)
  • 创建日期时间
  • 修改日期时间

【问题讨论】:

  • 表上有索引吗?
  • 你有什么索引?如果您能分享执行计划,那就太好了。
  • EXPLAIN 从统计表中获取有关 COUNT 的信息,该值是近似值。而查询给出了精确的结果。
  • @P.Salmon 是的。我确实有索引。
  • @VladimirPligin 我确实有大约 8 个索引用于多个过滤器,而 parent_id 就是其中之一。

标签: mysql sql innodb amazon-rds


【解决方案1】:

这在documentation on explain中有部分解释:

  • 行(JSON 名称:行)

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

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

我相信原因是因为explainINFORMATION_SCHEMA.TABLES.TABLE_ROWS 列中获取值。 documentation 进一步强调:

TABLE_ROWS

行数。一些存储引擎,例如 MyISAM,存储确切的计数。对于其他存储引擎,例如 InnoDB,这个值是一个近似值,可能与实际值相差 40% 到 50%。在这种情况下,请使用 SELECT COUNT(*) 获得准确的计数。

换句话说,当您使用SELECT COUNT(*) 时,无论存储引擎如何,MySQL 都会生成相同的查询计划。如果您碰巧知道使用INFORMATION_SCHEMA.TABLES 是安全的,那么您可以使用该值——因为您没有使用 InnoDB,或者因为一个近似值就足够了。

【讨论】:

    猜你喜欢
    • 2023-02-21
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多