关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题
1.关于count(1),count(*),和count(列名)的区别
相信大家总是在工作中,或者是学习中对于count()的到底怎么用更快。一直有很大的疑问,有的人说count(*)更快,也有的人说count(列名)更快,那到底是谁更快,我将会在本文中详细介绍一下到底是count(1),count(*)和count(列明)的区别,和更适合的使用场景。
往常在工作中有人会说count(1)比count(*)会快,或者相反,首先这个结论肯定是错的,实际上count(1)和count(*)并没有区别。
接下来,我们来对比一下count(*)和count(列)到底谁更快一些
首先我们执行以下sql,来看一下执行效率(下面sql针对的是ORACLE数据库,大致逻辑为先删除t别,然后在根据dba_objects创建t表,在更新t表根据rownum)
drop table t purge;
create table t as select * from dba_objects;
--alter table T modify object_id null;
update t set object_id =rownum ;
set timing on
set linesize 1000
set autotrace on --开启跟踪 select count(*) from t;
/
select count(object_id) from t;
/
然后咱们分别看一下“select count(*) from t”和“select count(object_id) from t”语句的执行计划。(执行计划是指sql的一个执行顺序和耗费的资源,耗费的资源越少越快,如果在plsql中,使用F8可以查看sql的执行计划)


通过我们执行sql的实验来说,count(*)和count(列)消耗的资源是一样的,说面他们是一样快的,但是真的是这样么。那么咱们接着以下的实验。
这次咱们给object_id这一列加一个索引试一下。我们执行一下索引sql
create index idx_object_id on t(object_id);
select count(*) from t;
/ select count(object_id) from t;
/
然后我们在分别看一下两条sql的执行计划


通过我们建完索引后。突然发现count(列)变快了好多,但是count(*)还是和以前一样的。这说明了count(列)可以用到索引,而count(*)不行,但是真的这样么,咱们在往下看。
接下来我们给object_id这个字段加上不可为空条件。我们执行以下sql
create index idx_object_id on t(object_id);
select count(*) from t;
/ select count(object_id) from t;
/
接下来我们在来看一下count(*)的执行计划

现在count(*)和count(列)一样快了,由此我们得出了这个结论:count(列)和count(*)其实一样快,如果索引列是非空的,count(*)可用到索引,此时一样快。
总结:但是真的结论是这样的么。其实不然。其实在数据库中count(*)和count(列)根本就是不等价的,count(*)是针对于全表的,而count(列)是针对于某一列的,如果此列值为空的话,count(列)是不会统计这一行的。所以两者根本没有可比性,性能比较首先要考虑写法等价,这两个语句根本就不等价。也就失去了去比较的意义!!!
2.关于表中字段顺序的问题
首先我们建一张有25个字段的表并加入数据在进行count(*)和count(列)比较。由于建表语句和插入语句和上面雷同。就不贴出代码了。
然后我们分别执行count(*)和count每一列的操作来看一下到底谁更快一些,由于执行计划太多,就不一一贴图了。我整理了一个excel来给大家看一下执行的结果

经过实验我们看出,count(列)越往后。我们的执行效率越慢。所以,我们得出以下结论:
1.列的偏移量决定性能,列越靠后,访问的开销越大。
2.由于count(*)的算法与列偏移量无关,所以count(*)最快。
总结:所以我们在开发设计中。越常用的列,要放在靠前的位置。而cout(*)和count(列)是两个不等价的用法,所以无法比较哪个性能更好,在实际的sql优化场景中要根据当时的业务场景再去考虑是使用count(*)还是count(列)(其中的区别上文有提到)。
关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题的更多相关文章
- SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int
--SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int --关键说明:--1.从系统表syscolumns中的查询所有xtype='48'的记录得到类型为[tinyint]的字段- ...
- 批量替换数据库中所有用户数据表中字段数据类型为char和varchar到nvarchar的脚本
解决问题:字段类型为char的总是占用指定字节长度(末尾好多空白符号),varchar数据类型长度一个汉字占2个字节,内容存储为中文的字段个人建议全部使用nvarchar. 操作说明:打开SQL Se ...
- 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器
一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...
- 修改MySQL数据库中表和表中字段的编码方式的方法
今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1 ...
- FlowPortal-BPM——功能:判断数据库表中字段是否重复并阻止提交或保存
一.JS添加代码,判断是否有OnSubmit事件 文件位置:YZSoft/Forms/src/Validator.js //=====判断是否有OnSubmit事件===== if (typeof ( ...
- SQLserver、MySQL、ORCAL查询数据库、表、表中字段以及字段类型
一.SQLServer命令 1.查询SQLServer中的每个数据库 SELECT * from sysdatabases 2.查询SQLServer中指定数据库的所有表名 select name f ...
- MYSQL数据库表中字段追加字符串内容
$sql="update parts set p_notes=concat(p_notes,'{$p_notes}') where p_id={$p_id}"; parts为表名 ...
- java怎样读取数据库表中字段的数据类型?
用DriverManager.getConnection()得到connect, 用connect.getMetaData()得到 DatabaseMetaData, 用 DatabaseMetaDa ...
- orcle数据库表中字段值含有单引号,如何模糊搜索?
例如:T_table表中,name字段值为:字符串含有‘单引号’: SQL模糊搜索语句应该如下:select * from T_table where name like '%含有''单引号''%'
随机推荐
- [codevs]1087麦森数
题目 这个题在noiOJ上是分治专题,这个题包括了很多,求位数,高精度乘,快速幂. 那么单独把这个高精度拿出来做一个自定义函数即可 一.求位数 显而易见,既然是2进制的就是log2X,是10进制就是l ...
- Angular杂谈系列2-Angular2升级Angular4指南
什么什么?Angualr4都发布了,之前不都才Angualr2的么?又要推翻重来,啊? 那当然不是,Angualr4只是一个版本号而已,本质上还是Angular2:以后,谷歌把新版本的Angualr称 ...
- ConcurrentHashMap、HashTable、HashMap的区别
HashTable与ConcurrentHashMap: 相同点:都是线程安全的,可以在多线程的环境下运行.key和value都不能为null 区别:性能上的差异.HashTable每次操作对象都会锁 ...
- NSLog (Log信息的输出)
概述 NSLog是 cocoa的框架中提供的一个方法 NSLog的定义 NSLog定义在NSObjCRuntime.h中 NSLog与printf的差异 1)NSLog传递进去的格式化字符是NSStr ...
- Ajax与Pjax请求在服务端是如何识别的
我在后台处理ajax和一般的网页请求时,一般是需要额外加个参数进行区分的.比如使用get参数的is_ajax=1,后台判断有is_ajax=1成立时,表明该请求是ajax请求,遂可区分处理.我正在使用 ...
- Java学习笔记——排序算法之快速排序
会当凌绝顶,一览众山小. --望岳 如果说有哪个排序算法不能不会,那就是快速排序(Quick Sort)了 快速排序简单而高效,是最适合学习的进阶排序算法. 直接上代码: public class Q ...
- <javaScript> 数组去重的方法总结(2017年)
现在要求去重下面这个数组: const arr = [1, 2, 3, 3, 3, '0', '1', '2', '测试', '重复', '重复', NaN, NaN, false, false]; ...
- 瀑布流布局使用详解——JQuery插件Isotope(动态实现子项目筛选)
瀑布流布局,听起来听牛逼的样子,其实就是简单的子元素筛选功能.不过这一功能在网站页面布局当中还是很常用的,特别是在电商网站中 经常会有点一个钮筛选,然后页面的子元素刷的以下变了样.接下来,我们先简单介 ...
- 【JS中循环嵌套常见的六大经典例题+六大图形题,你知道哪几个?】
首先,了解一下循环嵌套的特点:外层循环转一次,内层循环转一圈. 在上一篇随笔中详细介绍了JS中的分支结构和循环结构,我们来简单的回顾一下For循环结构: 1.for循环有三个表达式,分别为: ①定义循 ...
- kotlin 语言入门指南(三)--编码习惯
这章主要讲当前 kotlin 的一些编码习惯. 命名 如无疑问,kotlin 的命名风格与以下的java风格一样: --驼峰命名法(不要使用下划线) --类名首字母大写 --方法和属性名首字母小写 - ...