【问题标题】:select count(*) taking considerably longer than select * for same "where" clause?对于相同的“where”子句,select count(*) 比 select * 花费的时间要长得多?
【发布时间】:2014-02-26 09:07:06
【问题描述】:

我发现对于具有相同 where 子句的查询,select count(*)select * 花费的时间要长得多。

有问题的表有大约 220 万条记录(称为 detailtable)。它有一个外键字段链接到另一个表 (ma​​intable)。

此查询大约需要 10-15 秒:

select count(*) from detailtable where maintableid = 999

但这需要一秒钟或更短的时间:

select * from detailtable where maintableid = 999

UPDATE - 要求指定涉及的记录数。现在是 150。

UPDATE 2 以下是使用 EXPLAIN 关键字时的信息。

对于 SELECT COUNT(*)EXTRA 列报告:

Using where; Using index

KEYPOSSIBLE KEYS 都具有外键约束作为它们的值。

对于 SELECT * 查询,除了 EXTRA 只是说:

Using Where

UPDATE 3尝试了OPTIMIZE TABLE,但仍然没有任何作用。

【问题讨论】:

  • 请考虑将EXPLAIN 的全部输出发布到您的问题中。
  • + 表模式 + 有多少行(绝对值和百分比)满足给定条件?
  • count 查询返回的数字是多少?
  • 您是通过 Workbench、PHPMyAdmin、其他工具还是使用命令行运行查询?
  • 可能是缓冲/非缓冲查询的情况? ODBC 驱动程序或使用它的客户端设置了一个相对较小的缓冲区大小,MySQL 会迅速用首先找到的行填充它,并且在客户端消耗缓冲区并请求更多之前不继续表扫描?您是只测量了SELECT * 的执行,还是还测量了所有 150 条记录的检索?

标签: mysql


【解决方案1】:

试试

select count(PRIKEYFIELD) from detailtable where maintableid = 999
  1. count(*) 将从表中获取所有数据,然后计算行数,这意味着它还有更多工作要做。
  2. 使用主键字段意味着它正在使用它的索引,并且应该运行得更快。

【讨论】:

  • 即使是最差的查询规划器也应该同样对待COUNT(column)COUNT(*)COUNT(1)
【解决方案2】:

或者干脆试试

SELECT count(1) FROM table_name WHERE _condition;

SELECT count('x') FROM table_name WHERE _condition;

【讨论】:

    【解决方案3】:

    线程死灵!

    疯狂的想法...在某些情况下,取决于查询计划器和表大小等,使用索引实际上可能比不使用索引要慢。因此,如果您在不使用索引的情况下获得计数,在某些情况下,它实际上可能会更快。

    试试这个:

    SELECT count(*) 
      FROM detailtable 
     USING INDEX ()
     WHERE maintableid = 999
    

    【讨论】:

      【解决方案4】:
      SELECT count(*)
      

      仅使用该语法是没有问题的,您可以对任何表执行此操作。 您的方案的主要问题是正确使用 INDEX 并在搜索中应用 [WHERE] 子句。 如果有机会,请尝试重新配置您的索引。

      如果桌子太大,是的,这可能需要一些时间。尝试查看 MyISAM 锁定文章。

      【讨论】:

        【解决方案5】:

        由于该表有 220 万条记录,因此计数可能需要一些时间。从技术上讲,MySQL 应该找到记录然后对它们进行计数。这是一项额外的操作,对于数百万条记录而言意义重大。使其更快的唯一方法是将结果缓存在另一个表中并在后台更新它。

        【讨论】:

          【解决方案6】:

          肯定的

          select count(*)
          

          应该比

          select *
          

          count(*)、count(field)、count(primary key)、count(any)都是一样的。

          您的explain 明确指出优化器以某种方式使用count(*) 的索引,而不是其他使外键成为延迟的主要原因。

          消除外键。

          【讨论】:

            猜你喜欢
            • 2019-06-16
            • 1970-01-01
            • 2020-09-07
            • 1970-01-01
            • 1970-01-01
            • 2014-04-18
            • 1970-01-01
            • 2012-08-12
            • 1970-01-01
            相关资源
            最近更新 更多