MySQL优化之COUNT(*)效率
本文最后更新于 5940 天前,其中的信息可能已经有所发展或是发生改变。

刚给一个朋友解决他写的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的使用方法和效率研究》:https://kimi.pub/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' 的出现。

评论

  1. 16 年前
    2008-9-03 16:42:00

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

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

    • baidu-dba
      LVEYO
      13 年前
      2011-9-06 10:08:00

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

  2. 16 年前
    2008-9-13 12:18:42

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

  3. kiki
    16 年前
    2008-10-01 17:33:36

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

  4. 16 年前
    2008-10-13 23:46:43

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

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

  5. 16 年前
    2008-10-27 0:59:00

    幸好我一向用select count(*)

  6. 16 年前
    2008-11-05 13:53:33

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

  7. 博主
    16 年前
    2008-11-05 17:51:53

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

  8. guest
    16 年前
    2009-1-22 17:47:14

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

    只有MyIsam engine适用上面吧?

    • 博主
      guest
      16 年前
      2009-3-02 17:41:34

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

  9. guest
    16 年前
    2009-3-02 17:33:08

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

    • 博主
      guest
      16 年前
      2009-3-02 17:42:47

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

  10. 16 年前
    2009-3-24 18:20:57

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

    • 博主
      Daniel Hu
      16 年前
      2009-3-26 14:35:10

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

  11. 16 年前
    2009-4-10 17:05:55

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

    • 博主
      cevin91
      16 年前
      2009-4-11 18:20:26

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

  12. 15 年前
    2009-6-23 21:07:12

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

  13. 14 年前
    2010-11-18 22:52:06

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

  14. 14 年前
    2011-4-09 14:29:59

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

    • 博主
      fuck
      14 年前
      2011-4-11 20:04:43

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

  15. 童博
    14 年前
    2011-4-26 10:38:00

    什么结论都是有条件的

  16. 忠云
    14 年前
    2011-5-27 17:37:21

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

  17. ella
    13 年前
    2011-6-21 10:41:01

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

  18. ella
    13 年前
    2011-6-21 10:41:30

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

  19. 13 年前
    2011-10-04 22:46:59

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

  20. whatchamacallit
    13 年前
    2012-4-28 18:32:47

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

  21. 9 年前
    2016-1-25 11:37:42

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

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇