ITPUB论坛-专业的IT技术社区

标题: select count(*) 与 select count(1)区别? [打印本页]

作者: yangfei080    时间: 2008-5-8 14:19
标题: select count(*) 与 select count(1)区别?
我知道:
select   count(*)是统计表中所有记录个数
而select   count(1)是返回首行
后者的效率比前者要高

请问:
达人们能够解释下两者oracle内部实现的区别?
感谢!
作者: sdxiong    时间: 2008-5-8 15:01
我觉得两者应该是一样的。

看到有的人说count(*)时系统会选择某一列进行统计,但记得书上说过count(*)是不会对任何字段进行访问的。

至于楼主提到的count(1),个人觉得这只是一个常量,没特别的意思,并非1就是统计首列2就是统计第二列的意思,
因为count(0),count(-1),甚至count('a')也是可以的。

纯属个人意见,等待高手指点。。。
作者: star_guan2008    时间: 2008-5-8 15:02
buyiyang
作者: zhangweicai74    时间: 2008-5-8 15:22
以前有一个帖子专门说过这个问题,说是不一样,搜一下看下吧
作者: louis_xu    时间: 2008-5-8 15:35
原帖由 yangfei080 于 2008-5-8 14:19 发表
我知道:
select   count(*)是统计表中所有记录个数
而select   count(1)是返回首行
后者的效率比前者要高

请问:
达人们能够解释下两者oracle内部实现的区别?
感谢!


楼主理解错了,select count(1) 可不是返回首列行数
其原理是对数字1进行统计,会将表中所有记录转化为1,然后再计数统计
相当于先select 1 from table 然后count
作者: yangfei080    时间: 2008-5-8 16:38
标题: 回复 #5 louis_xu 的帖子
测试了一把,louis_xu 说的应该是对的

但是还是不太明白为什么 count(1) 要比 count(*)快呢?
按我的理解count(*)是直接统计记录行数,而count(1)要将每行记录转化为1再统计,应该是count(*)比count(1)快呀?
作者: microsoft_fly    时间: 2008-5-8 17:24
一般情况差不多,但
也不一定,看具体的执行计划

[ 本帖最后由 microsoft_fly 于 2008-5-8 17:31 编辑 ]
作者: junsansi    时间: 2008-5-8 17:55
count(*)与count(1)没啥区别

count(*) 不一定等于count(col)
作者: xinzaitian    时间: 2008-5-8 18:05
给yangfei080  有同感
  count(*)是直接统计记录行数,而count(1)要将每行记录转化为1再统计,应该是count(*)比count(1)快呀?
作者: 数据库游击队    时间: 2008-5-8 18:09
以前一直没有留意到COUNT(*)与COUNT(列名)的区别,昨天晚上无意中看到数据库系统工程师教程里面的一句话."如果null参与聚集运算,则除count(*)之外其它聚集函数都忽略null."
      这句话的意思说如果字段是有空值的话,你用SUM去计算,得到的结果有可能不准确.
    看一个实例.
    表A
    ID    EE
      1      e
      2    null
    select  count(*) from A  --结果是2
    select  count(EE)  from A  ---结果是1

http://error1983.blog.sohu.com/39734890.html
作者: HuiYiSky    时间: 2008-5-9 09:47
一样!
作者: wang5    时间: 2008-5-9 09:48
select count(1) from dual
作者: xiaodong_1567    时间: 2008-5-9 09:53
SQL> create table qq (x int,y int);

表已创建。

SQL> insert into qq values(1,1);

已创建 1 行。

SQL> insert into qq values(6,null);

已创建 1 行。

SQL> commit;

提交完成。

SQL> select count(*) from qq;

  COUNT(*)
----------
         2

SQL> select count(x) from qq;

  COUNT(X)
----------
         2

SQL> select count(y) from qq;

  COUNT(Y)
----------
         1
作者: louis_xu    时间: 2008-5-9 15:04
原帖由 yangfei080 于 2008-5-8 16:38 发表
测试了一把,louis_xu 说的应该是对的

但是还是不太明白为什么 count(1) 要比 count(*)快呢?
按我的理解count(*)是直接统计记录行数,而count(1)要将每行记录转化为1再统计,应该是count(*)比count(1)快呀?



跟表结构有关系:
如果表中没有主键,那么count(1)比count(*)快
如果有主键,那么count(主键,联合主键)比count(*)快
如果表中只有一个字段,count(*)最快
以前看一位高手说的,不知道为什么

[ 本帖最后由 louis_xu 于 2008-5-9 15:05 编辑 ]
作者: reggie_zb    时间: 2008-5-9 16:39
上面的问题还真没有注意过,谢谢楼上的!避免一次出错的机会,不过这种机会应该很少,一般的表的都是有key,怎么可能为空呢!呵呵
作者: liang573728    时间: 2008-5-9 17:00
学习了。以前还真没有留意count(*) count(1)的区别,还好一向使用count(*),要不然现在就麻烦了。
作者: asangel    时间: 2008-5-9 17:06
一般使用count(*)
作者: hongchaoyang    时间: 2008-5-9 21:58
原帖由 junsansi 于 2008-5-8 17:55 发表
count(*)与count(1)没啥区别

count(*) 不一定等于count(col)


嗯,
作者: chx3515    时间: 2008-5-10 11:28
count(*)、count(1) 基本没什么区别!!
作者: love_jia    时间: 2008-5-10 12:28
查看一下这两个sql 语句的执行计划
作者: lyyshui    时间: 2008-5-11 13:36
一直都是用count(*) ,还没有发现null的问题,先掌握下!
作者: jhua_lu    时间: 2009-3-12 16:30
SELECT子句中避免使用 ‘ * ‘
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.


计算记录条数
     和一般的观点相反, count(*) 比count(1)稍快 , 当然如果可以通过索引检索,对索引列的计数仍旧是最快的. 例如 COUNT(EMPNO)
  (译者按: 在CSDN论坛中,曾经对此有过相当热烈的讨论, 作者的观点并不十分准确,通过实际的测试,上述三种方法并没有显著的性能差别)




欢迎光临 ITPUB论坛-专业的IT技术社区 (http://www.itpub.net/) Powered by Discuz! X3.2