当前位置:  数据库>oracle

Oracle里count(1)、count(*)和count(主键)哪个更快

    来源: 互联网  发布时间:2017-06-25

    本文导语: Oracle里count(*)、count(1)和count(主键)到底哪个快的问题。这个问题看起来很简单,每个人都会有自己的答案,去百度上搜会出来一大堆帖子来讲哪个更快。但是说了它们三个其实是一样的,我听到之后也觉得挺诧异的,因为我记得...

Oracle里count(*)、count(1)和count(主键)到底哪个快的问题。这个问题看起来很简单,每个人都会有自己的答案,去百度上搜会出来一大堆帖子来讲哪个更快。但是说了它们三个其实是一样的,我听到之后也觉得挺诧异的,因为我记得别人跟我说过count(主键)会快,然后自己简单想了一下,觉得好像是那么回事的就没有深入去追究。接着老猫说官方有这样的说法这三个其实是等价的。晚上回来之后到MOS上查了一下,居然被我找到了How the Oracle CBO Chooses a Path for the SELECT COUNT(*) Command (文档 ID 124717.1)。这篇文档讲的就是在CBO优化器模式下,Oracle怎样去评估没有where条件select count(*)和select count(colum)语句的最优路径。

1、创建测试表并设计测试场景:

--创建测试表
sys@ORCL>create table journal_entries
  2  (id_je number(8) ,
  3  date_je date not null,
  4  balanced number ,
  5  constraint indx_ecr_id_je primary key(id_je)
  6  );
 
Table created.
--创建索引
sys@ORCL>create index indx_ecr_date_je_balanced on journal_entries(date_je,balanced);
 
Index created.
 
sys@ORCL>create index indx_ecr_balanced_date_je on journal_entries(balanced,date_je);
 
Index created.
 
sys@ORCL>create index indx_ecr_balanced on journal_entries(balanced);
 
Index created.
--插入测试数据
sys@ORCL>insert into journal_entries values(1,sysdate,11);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(2,sysdate,21);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(3,sysdate,31);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(4,sysdate,41);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(5,sysdate,51);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(6,sysdate,61);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(7,sysdate,71);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(8,sysdate,81);
 
1 row created.
 
sys@ORCL>insert into journal_entries values(9,sysdate,91);
 
1 row created.
 
sys@ORCL>commit;
 
Commit complete.
--收集统计信息
sys@ORCL>exec dbms_stats.gather_table_stats(ownname=>USER,tabname=>'JOURNAL_ENTRIES',cascade=>true);
 
PL/SQL procedure successfully completed.

设计四个场景进行对比:

Sel1 : Select count(*) from journal_entries;
Sel2 : Select count(1) from journal_entries;
Sel3 : Select count(id_je) from journal_entries;


Sel4 : Select count(balanced) from journal_entries;

1、场景1和场景2等价

For CBO, Sel1 and Sel2 are strictly equivalent

sys@ORCL>alter session set statistics_level=all;
 
Session altered.
 
sys@ORCL>select count(*) from journal_entries;
 
  COUNT(*)
----------
        9
 
sys@ORCL>select * from table(dbms_xplan.display_cursor(null,null,'runstats_last'));
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5ja3ukp4wd73p, child number 0
-------------------------------------
select count(*) from journal_entries
 
Plan hash value: 42135099
 
---------------------------------------------------------------------------------------------
| Id  | Operation        | Name          | Starts | E-Rows | A-Rows |  A-Time  | Buffers |
---------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT |                |      1 |        |      1 |00:00:00.01 |      1 |
|  1 |  SORT AGGREGATE  |                |      1 |      1 |      1 |00:00:00.01 |      1 |
|  2 |  INDEX FULL SCAN| INDX_ECR_ID_JE |      1 |      9 |      9 |00:00:00.01 |      1 |
---------------------------------------------------------------------------------------------
 
14 rows selected.
 
sys@ORCL>select count(1) from journal_entries;
 
  COUNT(1)
----------
        9
 
sys@ORCL>select * from table(dbms_xplan.display_cursor(null,null,'runstats_last'));
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  gbxjjuqj9j7ww, child number 0
-------------------------------------
select count(1) from journal_entries
 
Plan hash value: 42135099
 
---------------------------------------------------------------------------------------------
| Id  | Operation        | Name          | Starts | E-Rows | A-Rows |  A-Time  | Buffers |
---------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT |                |      1 |        |      1 |00:00:00.01 |      1 |
|  1 |  SORT AGGREGATE  |                |      1 |      1 |      1 |00:00:00.01 |      1 |
|  2 |  INDEX FULL SCAN| INDX_ECR_ID_JE |      1 |      9 |      9 |00:00:00.01 |      1 |
---------------------------------------------------------------------------------------------
 
 
14 rows selected.

可以看到两个语句的执行计划是完全相同的。

2、场景3也与前两个场景等价,因为id_je有NOT NULL约束

For Sel3, CBO does the same as for Sel1 and Sel2 since "id_je" has a NOT NULL constraint.

sys@ORCL>select count(id_je) from journal_entries;
 
COUNT(ID_JE)
------------
          9
 
sys@ORCL>select * from table(dbms_xplan.display_cursor(null,null,'runstats_last'));
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  b1p4v15dwx7hs, child number 0
-------------------------------------
select count(id_je) from journal_entries
 
Plan hash value: 42135099
 
---------------------------------------------------------------------------------------------
| Id  | Operation        | Name          | Starts | E-Rows | A-Rows |  A-Time  | Buffers |
---------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT |                |      1 |        |      1 |00:00:00.01 |      1 |
|  1 |  SORT AGGREGATE  |                |      1 |      1 |      1 |00:00:00.01 |      1 |
|  2 |  INDEX FULL SCAN| INDX_ECR_ID_JE |      1 |      9 |      9 |00:00:00.01 |      1 |
---------------------------------------------------------------------------------------------
 
 
14 rows selected.

可以看到执行计划与前两个也是完全相同的。

4、场景4跟前边3个不同,因为balanced列上没有NOT NULL约束,但是balanced列上有索引,那会走这个列上的索引么?我们来看一下执行计划:

sys@ORCL>select count(balanced) from journal_entries;
 
COUNT(BALANCED)
---------------
              9
 
sys@ORCL>select * from table(dbms_xplan.display_cursor(null,null,'runstats_last'));
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bc3bc8c0fg14z, child number 0
-------------------------------------
select count(balanced) from journal_entries
 
Plan hash value: 3638043346
 
--------------------------------------------------------------------------------------------------------
| Id  | Operation        | Name                      | Starts | E-Rows | A-Rows |  A-Time  | Buffers |
--------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT |                          |      1 |        |      1 |00:00:00.01 |      1 |
|  1 |  SORT AGGREGATE  |                          |      1 |      1 |      1 |00:00:00.01 |      1 |
|  2 |  INDEX FULL SCAN| INDX_ECR_DATE_JE_BALANCED |      1 |      9 |      9 |00:00:00.01 |      1 |
--------------------------------------------------------------------------------------------------------
 
14 rows selected.

我们看到这个执行计划没有走balanced列上的索引,而是走了和date_je的联合索引。这个可以查看另一篇文档:Note:67522.1 Why is my index not used?

小结一下:

我这里只是简单的从执行计划上看count(*)、count(1)和count(主键)其实是一致,MOS的文档中详细的讲解了Oracle是如何评估执行计划的,也可以使用10053 event查看CBO优化器是如���做出选择的。由于我的功力还不够,对于10053事件还不是很明白,暂时就先不做演示了,要不哪说错了就不好了,这也可以做为以后博客分享的内容。

从这个事情上来看,我们对于一件事情应该做一个深入的研究,有充足的证据来证明,尤其是想要在某一方面有深入发展的时候。


    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Oracle 12c发布简单介绍及官方下载地址
  • 在linux下安装oracle,如何设置让oracle自动启动!也就是让oracle那个服务自动启动,不是手动的
  • oracle 11g最新版官方下载地址
  • 请问su oracle 和su - oracle有什么不同?
  • Oracle 数据库(oracle Database)Select 多表关联查询方式
  • 虚拟机装Oracle R12与Oracle10g
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • Oracle 数据库开发工具 Oracle SQL Developer
  • 如何设置让Oracle SQL Developer显示的时间包含时分秒
  • Oracle EBS R12 支持 Oracle Database 11g
  • Oracle 10g和Oracle 11g网格技术介绍
  • SCO unix下安装oracle,但没有光盘,请大家推荐一个oracle下载站点(unix版本的)。谢谢!!!!
  • oracle中如何把表中具有相同值列的多行数据合并成一行
  • 请问大家用oracle数据库, 用import oracle.*;下的东西么? 还是用标准库?
  • Oracle 数据库(oracle Database)性能调优技术详解
  • Linux /$ORACLE_HOME $ORACLE_HOME
  • ORACLE日期相关操作
  • Linux系统下Oracle的启动与Oracle监听的启动
  • ORACLE数据库常用字段数据类型介绍
  • 请问在solaris下安装ORACLE,用root用户和用oracle用户安装有什么区别么?
  • Oracle 12c的九大最新技术特性介绍
  • 网间Oracle的连接,远程连接Oracle服务器??


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3