loading...

MySQL优化之COUNT(*)效率

发布时间:September 3, 2008 分类:MySQL

Xdebug终极教程

Nginx下Discuz!的Rewrite

刚给一个朋友解决他写的Discuz!插件的问题,说到MySQL的COUNT(*)的效率,发现越说越说不清楚,干脆写下来,分享给大家。

COUNT(*)与COUNT(COL)
网上搜索了下,发现各种说法都有:
比如认为COUNT(COL)比COUNT(*)快的;
认为COUNT(*)比COUNT(COL)快的;
还有朋友很搞笑的说到这个其实是看人品的。

不加WHERE限制条件的情况下,COUNT(*)与COUNT(COL)基本可以认为是等价的;
但是在有WHERE限制条件的情况下,COUNT(*)会比COUNT(COL)快非常多;

具体的数据参考如下:

mysql> SELECT COUNT(*) FROM cdb_posts where fid = 604;
+------------+
| COUNT(fid) |
+------------+
| 79000 |
+------------+
1 row in set (0.03 sec)

mysql> SELECT COUNT(tid) FROM cdb_posts where fid = 604;
+------------+
| COUNT(tid) |
+------------+
| 79000 |
+------------+
1 row in set (0.33 sec)

mysql> SELECT COUNT(pid) FROM cdb_posts where fid = 604;
+------------+
| COUNT(pid) |
+------------+
| 79000 |
+------------+
1 row in set (0.33 sec)

COUNT(*)通常是对主键进行索引扫描,而COUNT(COL)就不一定了,另外前者是统计表中的所有符合的纪录总数,而后者是计算表中所有符合的COL的纪录数。还有有区别的。

COUNT时的WHERE
这点以前就写过,详细请看《Mysql中count(*),DISTINCT的使用方法和效率研究》:http://www.ccvita.com/156.html

简单说下,就是COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数
而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。

优化总结,对于MyISAM表来说
1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;
2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = 'value' 这种查询;
3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = 'value' 的出现。

Tags: MySQL优化, MySQL效率


已有 27 条评论 »

  1. LVEYO LVEYO

    在oracle中count(col)的性能就会好于count(*)

    看来数据库中的差异还是挺大的,sql的优化不能一概而论啊。

    1. baidu-dba baidu-dba

      @LVEYO,
      你说错了!oracle中对count是有优化特殊处理的,并不是你想的count(*)就比count(col)差,二者是相同的。你可以使用dbms_xplan查看具体的执行计划,并做个大表试试。

  2. 无聊空间 无聊空间

    我一般都是select count(1) from tables , 那个1是不存在的字段

  3. kiki kiki

    你好... 最近想学MYSQL 之前用的是SQL SERVER 2000 然后去载了个PHPMYADMIN 但是配置文件一直出错 打不开 能不能帮忙解决下??

  4. yayu yayu

    除了考虑效率,还得结合实际情况。

    比如,如果要查询的字段可能有null值,而又想排除这条数据,就只能用count(col)了

  5. 松山之鹰 松山之鹰

    幸好我一向用select count(*)

  6. 枫叶 枫叶

    其时个人感觉count(*)的确要比别的都快,但是,据我上次测试后发现sum(1)的速度在特定的条件下面要比count(*)快。

  7. kimi kimi

    @枫叶 具体点呢,什么情况下sum(1)的效率会更好的呢?

  8. guest guest

    "简单说下,就是COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数
    而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。"

    只有MyIsam engine适用上面吧?

    1. kimi kimi

      @guest, 好的,本文是针对MyIsam

  9. guest guest

    1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;
    对这点有个凝问
    假设表A,有个文本字段,平均每条记录文本大小为200个汉字,表记录条数在50w左右。是否还是SELECT COUNT(*) FROM tablename最优呢?

    1. kimi kimi

      @guest, 是的,不加WHERE的查询,MySQL直接返回保存有总的行数

  10. Daniel Hu Daniel Hu

    COUNT(*)与COUNT(COL)首先在统计的数据上就有不同。COUNT(*)统计的是记录集的记录数,COUNT(COL)返回的是记录集中COL的value不为null的记录数。两者还有有区别的,所以在某些场合是不能彼此替换的。我的理解是这样的http://hi.baidu.com/dearhwj/blog/item/3a45b28de358031ab31bba1b.html,如果有不正确的地方请赐教!

    1. kimi kimi

      @Daniel Hu, 感谢你的回复,你发的地址,对本文是一个很好的补充:)

  11. cevin91 cevin91

    在没有索引的情况下count(field)会快很多?

    1. kimi kimi

      @cevin91, 任何情况下SELECT COUNT(*) FROM tablename是最优选择

  12. jackbillow jackbillow

    不是很同意兄弟的说法.
    我测试的结果,是带where条件下,count(pk)比count(*)快些.

  13. ymhsky ymhsky

    学习了,呵呵,用这好几年MYSQL,还真的没有测试过,有时候,我用count(1)的,不知效率又是怎样,找时间测试一下。

  14. fuck fuck

    大哥 你的总结是错的!!! 误人子弟

    1. kimi kimi

      @fuck, 对于MyISAM表来说,是这样的啊

  15. 童博 童博

    什么结论都是有条件的

  16. 忠云 忠云

    学习了,以前没有看到过,今天看了以后受到了教育。以前,我总粗略的认为 count(某个字段)会比count(*)快,现在看来不能随便猜想!感谢!

  17. ella ella

    楼主的观点是错误的。我已经验证过啦。误人啊

  18. ella ella

    楼主的观点是错误的。我已经验证过啦。

  19. 苏斌 苏斌

    写的真好,最近在查mysql XXX 效率 的时候都是你的站排在最前面, 记得第一次访问你的站的时候还是在前公司里,两年以前了。

  20. whatchamacallit whatchamacallit

    SELECT count(0) FROM TABLE; 你有没有试过比较这种的效率?

  21. Will Will

    gravatar头像没有显示,修改一下吧。
    换成国内的就OK了

添加新评论 »

captcha
请输入验证码