阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

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

399次阅读
没有评论

共计 6790 个字符,预计需要花费 17 分钟才能阅读完成。

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 事件还不是很明白,暂时就先不做演示了,要不哪说错了就不好了,这也可以做为以后博客分享的内容。

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

更多 Oracle 相关信息见 Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-12/138685.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计6790字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19350
评论数
4
阅读量
7884617
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...
手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板 前言 大家好,我是星哥。星哥发现很多新手刚接触服务器时,都会被“选购...
CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流! 大家好,我是星哥,今天才思枯竭,不写技术文章了!来吐槽一下 CSDN。...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

  300 元就能买到的 ” 小钢炮 ”?惠普 7L 四盘位小主机解析 最近...
恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击 PHP-FPM(FastCGl Process M...
星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定! 前言 作为 NAS 玩家,你是否总被这些...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...