select count(*)、count(1)、count(主键列)和count(包含空值的列)有何区别?

简介: 下班路上看见网上有人问一个问题: oracle 10g以后count(*)和count(非空列)性能方面有什么区别?乍一看,确实有些含糊,Oracle中往往小问题蕴含着大智慧,如何破云见日?最直接的方法,我想就是通过10053事件,来看下不同SQL对应的执行计划和资源消耗等情况,进而看看是否有些信息可以为我们所用。

下班路上看见网上有人问一个问题:

oracle 10g以后count(*)和count(非空列)性能方面有什么区别?

乍一看,确实有些含糊,Oracle中往往小问题蕴含着大智慧,如何破云见日?

最直接的方法,我想就是通过10053事件,来看下不同SQL对应的执行计划和资源消耗等情况,进而看看是否有些信息可以为我们所用。

首先,准备测试数据,11g库表bisal的id1列是主键(确保id1列为非空),id2列包含空值,
这里写图片描述

我们分别用10053打印如下4组SQL的trace,

SQL1:select count(*) from bisal;
SQL2:select count(1) from bisal;
SQL3:select count(id1) from bisal;
SQL4:select count(id2) from bisal;

我们来看下这四个SQL的执行结果,
这里写图片描述
前三个均为表数据总量,第四个SQL结果是99999,仅包含非空记录数据量,说明若使用count(允许空值的列),则统计的是非空记录的总数,空值记录不会统计,这可能和业务上的用意不同。

我们在看下这四个SQL对应的执行计划,前三个SQL执行计划相同,均为对主键索引的快速索引全扫描,
这里写图片描述

第四个SQL执行计划,则是全表扫描,
这里写图片描述

其实这无论id2是否包含空值,使用count(id2)均会使用全表扫描,因此即使语义上使用count(id2)和前三个SQL一致,这种执行计划的效率也是最低的,这张测试表的字段设置和数据量不很夸张,因此不很明显,如果数据表字段多、数据量大,显然主键索引占用的数据块要比数据表占用的数据块少,因此仅索引扫描,而且是全索引快速扫描(多块读),消耗的资源会更少些了。

再看前三个SQL对应的trace,第1个SQL,
这里写图片描述

这里写图片描述

第二个SQL,
这里写图片描述

这里写图片描述

第三个SQL,
这里写图片描述

这里写图片描述

可以看出一个问题,就是这三个SQL经过Oracle转换,执行的SQL其实都是select count(*) from bisal,因此对应的执行计划成本选择,这三个SQL相同,
这里写图片描述
比较了全表扫描、索引快速全扫描以及全索引扫描这三种扫描方式的成本,都选择了主键索引的FFS扫描方式。

总结:
11g下,通过实验结论,说明了count()、count(1)和count(主键索引字段)其实都是执行的count(),而且会选择索引的FFS扫描方式,count(包含空值的列)这种方式一方面会使用全表扫描,另一方面不会统计空值,因此有可能和业务上的需求就会有冲突,因此使用count统计总量的时候,要根据实际业务需求,来选择合适的方法,避免语义不同。

欢迎关注我的个人微信公众号:bisal的个人杂货铺
这里写图片描述

目录
相关文章
|
SQL 缓存 Oracle
为什么阿里巴巴禁止使用 count(列名)或 count(常量)来替代 count(*)
本文介绍了COUNT函数的用法,主要用于统计表行数。主要用法有COUNT(*)、COUNT(字段)和COUNT(1)。
11688 0
为什么阿里巴巴禁止使用 count(列名)或 count(常量)来替代 count(*)
|
14天前
|
数据库
count(1)、count(*)、count(column)的含义、区别、执行效率
总之,`count(1)` 和 `count(*)` 通常会更常用,因为它们的执行效率较高,不涉及对具体列值的处理。而 `count(column)` 适用于统计特定列中的非空值数量。在实际使用时,可以根据情况选择适合的方式。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
12 0
|
5月前
|
存储 SQL 关系型数据库
count(1)、count(具体字段)和count(*)究竟有什么区别?
count(1)、count(具体字段)和count(*)究竟有什么区别?
57 0
|
6月前
|
SQL Serverless 数据库
【count(列名)、count(1)和 count(星号)有什么区别】
【count(列名)、count(1)和 count(星号)有什么区别】
|
8月前
|
SQL 数据可视化 关系型数据库
count(列名) ,count(1)与count(*) 有何区别?
count(列名) ,count(1)与count(*) 有何区别?
|
9月前
|
关系型数据库 MySQL 索引
【MySQL】count(1)、count(*)、count(字段)、count(主键)的区别
【MySQL】count(1)、count(*)、count(字段)、count(主键)的区别
163 0
|
10月前
|
存储 关系型数据库 MySQL
MySQL中count是怎样执行的?———count(1),count(id),count(非索引列),count(二级索引列)的分析
MySQL中count是怎样执行的?———count(1),count(id),count(非索引列),count(二级索引列)的分析
113 0
MySQL中count是怎样执行的?———count(1),count(id),count(非索引列),count(二级索引列)的分析
|
10月前
|
SQL 索引
Count(1) Count(0) Count(*) Count(列名)
Count(1) Count(0) Count(*) Count(列名)
112 0
|
11月前
|
SQL 数据库
数据库sql语句(count(*)和count(字段))
数据库sql语句(count(*)和count(字段))
148 0
|
存储 SQL 架构师
性能大PK count(*)、count(1)和count(列)
最近的工作中,我听到组内两名研发同学在交流数据统计性能的时候,聊到了以下内容: 数据统计你怎么能用 count(*) 统计数据呢,count(*) 太慢了,要是把数据库搞垮了那不就完了么,赶紧改用 count(1),这样比较快...... 有点儿好奇,难道 count(1) 的性能真的就比 count(*) 要好吗? 印象中网上有很多的文章都有过类似问题的讨论,那 MySQL 统计数据总数 count(*) 、count(1)和count(列名) 哪个性能更优呢?今天我们就来聊一聊这个问题。
性能大PK count(*)、count(1)和count(列)