场景:
一张总表中,进行统计某个用户发文章的数据量。其中统计到400多W条数据。
优化:
总表X字段已经做过索引。其中x字段是int(11).
查询:
select count(*) from alltable where x = 1;
结果:
基本上都是20秒以上。
explain:
explain select count(*) from alltable where x = 1;
+----+-------------+---------+------+---------------+--------+---------+-------+---------+--------------------------+
| id | select_type | table   | type | possible_keys | key    | key_len | ref   | rows    | Extra                    |
+----+-------------+---------+------+---------------+--------+---------+-------+---------+--------------------------+
|  1 | SIMPLE      | alltable | ref  | x        | x | 5       | const | 4030933 | Using where; Using index | 
+----+-------------+---------+------+---------------+--------+---------+-------+---------+--------------------------+请问一下。这个是怎么回事?

解决方案 »

  1.   

    count(*)结果是多少?索引如果选择度不高的话,效果有限
      

  2.   

    show index from alltable 
      

  3.   

    不正常的,我用postgres统计1000W数据也才2秒test=# \timing 
    Timing is on.
    test=# select count(1) from tbl_analyze;
      count   
    ----------
     10230251
    (1 row)Time: 2096.391 ms
    test=# 
      

  4.   

    看一下explain.选择度应该是没问题。
      

  5.   

    show index from alltable;
    +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
    +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | alltable |          0 | PRIMARY  |            1 | id          | A         |        NULL |     NULL | NULL   |      | BTREE      |         | 
    | alltable |          1 | x   |            1 | x      | A         |           1 |     NULL | NULL   | YES  | BTREE      |         | 
    +---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
      

  6.   

    哥们,你这样是很快的。在myisam中。没有带WHERE的情况下,两秒多算慢了。
      

  7.   

    mysql count(*) 统计查询,如果带条件都是很慢的,如果不带条件就很快,不知什么方案可以使带条件统计也可以快.
      

  8.   

    1、建议不要用count(*),  count(主键ID)或count(1).
    2、看看你所创建的索引。
      

  9.   

    count(*)是在没有where条件下很快
    如果大多都一样,思路反向测试下
    方法一:select (select count(*) from alltable)-count(*) from alltable where x <> 1;
    或者使用sum
    方法二:select sum(if(x=1,1,0)) from alltable  ;
    还可以使用count不统计null的方式实现
    方法三:select count(x=1 or null) from alltable  ;
    因我这里没环境,你可以测试下这三种方式的效率
      

  10.   

    后面两个是在存在多个不同值统计时使用。
    count(*)在mysql中不会扩展成所有列的,他会忽略所有列统计所用行数
      

  11.   

    表里面有个创建时间的话
    先把每个用户截止于今天凌晨之前的发表文章数计算出来 
    这个记录可以每日用event 去计算 放在一张临时表 x字段加上索引、
    比如x =1 在 <2013-05-20 00:00:00 总数是 188 
    今天发表文章数 是 10总的就是 188+10 
    而实时去查询
    select count(*) from alltable where x = 1 and create_time>=curdate();
    要是  create_time 有索引的话效率是不慢的。 
      

  12.   

    如果这个结果集会频繁调用的话建议启动一个程序专门用来计算count的结果放在另一个表里面,而且当想要结果的时候就访问这个新建的表好了