最好不用count(*),要用count(字段)
因为count(*),要分析所有的字段,所以执行慢很多,而count(字段)分析具体的字段所以执行快很多

解决方案 »

  1.   

    count(*)时oracle不会自己优化吗?
      

  2.   

    不能同意楼上观点;
      COUNT(*)
    ----------
       1295346已选择 1 行。已用时间:  00: 00: 00.08
    COUNT(PBIID)
    ------------
         1295346已选择 1 行。已用时间:  00: 00: 01.02
    其实对count(*) 的时候,ORACLE是不要进行字段的判断的。但是用count(pbiid)是要分析字段的,至少要判断字段的存在与否!
      

  3.   

    如果在字段上有唯一索引的话,count(字段)会快些
      

  4.   

    我觉得似乎count(*)该快一些,应为不论什么查询oracle都会产生一个游标,而count(*)返回的就是sql%rowcount;而count(列名)在返回时还要判断该值是否为空,所以会慢一些。以上是个人意见,如有错误请多多指教
      

  5.   

    不好意思.没有及时回复.count(*) 快是否就如 zealot_zk(风中追风) 所说的了?但如果只是count(column)的话,没必要判空啊?chanet(牧师) , l2g32003(T2-X)可以解释的清除一些吗。
    谢谢大家!
      

  6.   

    count只是一个函数,它的执行难道就是返回内建游标的sql%rowcount属性吗?
      

  7.   

    刚刚我把一张有十三万条记录的表进行了测试.结果如下:Select Count(*) From m_sendmaterial  1.938秒
    Select Count(SENDID) From m_sendmaterial   0.094秒   SENDID为主键字
    Select Count(ASEND) From m_sendmaterial   0.109秒    ASEND为一般字段也就是说从效率上来说count(主键)是最快的.
      

  8.   

    谢谢liuyi8903(西西)!你用的什么方式计时啊?怎么大侠们不来回答一下了,使这个问题太无聊了?
      

  9.   

    我用的是pl/sql工具来计时呀.工具提供这个功能的.
      

  10.   

    刚刚我把一张有十三万条记录的表进行了测试.结果如下:Select Count(*) From m_sendmaterial  1.938秒
    Select Count(SENDID) From m_sendmaterial   0.094秒   SENDID为主键字
    Select Count(ASEND) From m_sendmaterial   0.109秒    ASEND为一般字段也就是说从效率上来说count(主键)是最快的.-----------------------------------------------
    请注意,SQL的运行有第一次运行与第N次运行的差别,我想你第一个COUNT(×)那么慢,是第一次运行的结果吧,你多来几次就会发现它实际上并没有那么慢从实际运行结果来看,各种方法并没有明显的差异。
      

  11.   

    **********************************************
      本人做以下测试!!
      说明:
          fnd_user表上user_id,user_name上都有索引,
      还有别的列上也有索引.
    *********************************************测试一:
    SQL> select count(*) from fnd_user a ; COUNT(*)
    ---------
          467
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1)
       1    0   SORT (AGGREGATE)
       2    1     INDEX (FULL SCAN) OF 'FND_USER_U1' (UNIQUE) (Cost=1 Card
              =420)Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              1  consistent gets
              0  physical reads
              0  redo size
            170  bytes sent via SQL*Net to client
            308  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              1  rows processed          
              
              
    --***************************************************************************************************
    测试二
    SQL> select count(a.user_id) from fnd_user a;COUNT(A.USER_ID)
    ----------------
                 467
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1)
       1    0   SORT (AGGREGATE)
       2    1     INDEX (FULL SCAN) OF 'FND_USER_U1' (UNIQUE) (Cost=1 Card
              =420)Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              1  consistent gets
              0  physical reads
              0  redo size
            178  bytes sent via SQL*Net to client
            308  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              1  rows processed
           
           
           
           
           
              
    ---*************************************************************************************************
    测试三:
    SQL> select count(a.user_name) from fnd_user a ;COUNT(A.USER_NAME)
    ------------------
                   467
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1)
       1    0   SORT (AGGREGATE)
       2    1     INDEX (FULL SCAN) OF 'FND_USER_U1' (UNIQUE) (Cost=1 Card
              =420)Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              1  consistent gets
              0  physical reads
              0  redo size
            180  bytes sent via SQL*Net to client
            308  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              1  rows processed
              
              
    结论:使用select count(*) from table   和  select count(字段) from table,系统将自动使用第一个索引进行全表扫描计算.
      

  12.   

    补充 
        FND_USER_U1  第一个字段  user_id上的索引的索引名.
      

  13.   

    现做的测试。
    数据库是ORACLE9I,此测试是在该数据库的图形管理工具里面,用SQL SCRATCHPAD工具直接分析SQL语句,并执行得出的结果,应该是比较权威的。结果表明两种方式的执行步骤完全是一模一样,执行结果也一样。表名:dat_mywb
    记录数:173318执行时间:0.43秒
    select count(*) from hch.dat_mywb SQL语句执行步骤
    1.此计划步骤检索表 DAT_MYWB 中的所有行。
    2.此计划步骤接受一个行集合 (其唯一的子级行) 并通过应用聚集函数返回单个行。
    3.此计划步骤将该语句指定为 SELECT 语句。执行时间:0.43秒
    select count(mwb_id) from hch.dat_mywb SQL语句执行步骤
    1.此计划步骤检索表 DAT_MYWB 中的所有行。
    2.此计划步骤接受一个行集合 (其唯一的子级行) 并通过应用聚集函数返回单个行。
    3.此计划步骤将该语句指定为 SELECT 语句。