count()聚合计算

count()是聚合函数,对于返回的结果集,一行行地判断,累计值加1,最后返回累计值,count(*)、count(主键ID)和count(1)表示返回满足条件的结果集的总行数。

count()聚合函数统计非NULL与NULL值的区别:

1、count(字段)不统计NULL记录,即表示满足条件的数据行里参数字段不为NULL的行

2、count(1)和count(*)会记录NULL值

count(主键ID)、count(字段)、count(1)、count(*)的区别和性能差异(分析性能差别的原则)
  1、server层要什么就给什么 
  2、InnoDB只给必要的值
  3、现在的优化器对count(*)的取行数做了优化,其他没有做优化
 
count(主键ID)比count(1)慢的原因
  对于 count(主键 ID) 来说,InnoDB 引擎会遍历主键索引树,把每一行的ID值取出来,返回给server层,server层拿到ID后,判断是不可能为空的,按行累加加1,最后返回累计值。
  对于count(1),InnoDB引擎会扫描主键索引树,但不取值,server层对于返回的每一行,按行累计加1,判断不可能为NULL,返回累计值。
  从InnoDB引擎层返回ID会涉及到解析数据行、拷贝字段值的操作,因此count(主键 ID)执行要比count(1)执行慢。
 
count(字段)
  1、如果这个字段定义为not null的话,一行行地从记录里面读出这个字段,判断不能为null,按行累计加1
  2、如果这个字段定义允许为null,一行行地从记录里面读出这个字段,执行的时候还要判断是否为null,不为null的按行累计加1,返回累加值
  
count(主键id)走主键索引的时候效率较count(*)差的原因?
  平时我们检索一列的时候,基本上等值或范围查询,那么索引基数大的索引必然效率很高(符合走主键索引查找速度最快的原则)。
  但是在做count(*)的时候并没有检索具体的一行或者一个范围,那么选择基数小的索引对count操作效率会更高。在做count操作的时候,mysql会遍历每个叶子节点,所以基数越小,效率越高。mysql非聚簇索引叶子节点保存指向主键ID的指针,所以需要检索两遍索引。但是这里相对于遍历主键索引,即使检索两遍索引效率也比单纯的检索主键索引快。
  Innodb是索引组织表,主键索引树的叶子节点是数据,而普通索引树的叶子节点是主键值,索引普通索引树小很多,索引长度越小树的大小就越小。
 
MyISAM与InnoDB,正如在不同的存储引擎中,count(*)函数的执行是不同的
  在MyISAM存储引擎中,count()函数是直接读取数据表保存的行记录数并返回,效率很高,但是如果添加了where条件的话,MyISAM表也不能返回得很快。
  在InnoDB存储引擎中,count(*)函数是先从内存中读取表中的数据到内存缓冲区,然后扫描全表获得行记录数。在使用count函数中加上where条件时,在两个存储引擎中的效果是一样的,都会扫描全表计算某字段有值项的次数。
count(*)中关于select count(*) from tab_name几种不走索引和走那种索引情景分析
CREATE TABLE `t1` (
`c1` varchar(30) NOT NULL,
`c2` varchar(20) NOT NULL,
`c3` varchar(40) NOT NULL,
`c4` varchar(10) DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ceshi_count'

1、表中没有任何索引(表也没有主键)

mysql> explain select count(*) from t1;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 1 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.01 sec)

2、表有主键则执行主键索引全扫描

mysql> alter table t1 add primary key (c1);
Query OK, 0 rows affected (0.16 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select count(*) from t1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | PRIMARY | 92 | NULL | 1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

3、表有二级索引,则使用二级索引key_len最小的索引进行扫描,尽管这个二级索引的key_len的值大于主键,都使用二级索引

mysql> alter table t1 add index idx_c3(c3);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select count(*) from t1;
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | idx_c3 | 122 | NULL | 1 | Using index |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
1 row in set (0.00 sec)

4、表有多个二级索引,则使用key_len小的二级索引进行扫描

mysql> alter table t1 add index idx_t1_c4(c4);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select count(*) from t1;
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | idx_t1_c4 | 33 | NULL | 1 | Using index |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
1 row in set (0.00 sec)
取表行数的几种方式
  1、count(*)取行数
  2、通过infomation_schema可以快速拿到表的count值,但不是一个准确的值,通过show table status like 'tab_name'查找到的table rows是通过采样方式得到行数,它的误差率达到了40到50%,
  3、MyISAM会存储具体的行数(可能因为myISAM事务要加表锁,才这样设计),InnoDB则需要进行全表扫描

count()聚合函数正确用法的更多相关文章

  1. having,groub by 结合聚合函数的用法解析

    聚合函数有:sum , count, avg, max等等: where无法与聚合函数一起使用,所以在sql语句中加上having子句来筛选查询结果: 上面的sql语句是错的,正确如下: SELECT ...

  2. Django查找数据库objects.filter() 排序order_by Q()与或非 F()属性之间比较 聚合函数的用法

    条件选取QuerySet的时候,filter表示=参数可以写查询条件,exclude表示!=,querySet.distinct() 去重复(除了get返回值都是QuerySet,可以继续调用所有函数 ...

  3. oracle聚合函数XMLAGG用法简介

    XMLAGG函数语法基本如图,可以用于列转行,列转行函数在oracle里有好几种方法,wm_concat也可以做 这里介绍wm_concat是因为XMLAGG实现效果和wm_concat是一样的,只是 ...

  4. sql中having、group by用法及常用聚合函数

    having是用在聚合函数的用法.当我们在用聚合函数的时候,一般都要用到GROUP BY 先进行分组,然后再进行聚合函数的运算.运算完后就要用到HAVING 的用法了,就是进行判断了. 注意:sele ...

  5. group by 和聚合函数

    group by 的基本用法 group by做为分组来使用,后面为条件,可以有多个条件,条件相同的为一组,配合聚合函数进行相关统计.在不同数据库中用法稍有不同,这里只测试mysql和oracle. ...

  6. sqlserver的over开窗函数(与排名函数或聚合函数一起使用)

    首先初始化表和数据 create table t_student(   Id INT,   Name varchar(),   Score int,   ClassId INT ); insert i ...

  7. LitePal的聚合函数

    传统的聚合函数用法   虽说是聚合函数,但它的用法其实和传统的查询还是差不多的,即仍然使用的是select语句.但是在select语句当中我们通常不会再去指定列名,而是将需要统计的列名传入到聚合函数当 ...

  8. 72.Python中ORM聚合函数详解:Avg,aggregate,annotate

    聚合函数: 如果你用原生SQL语句,则可以使用聚合函数提取数据.比如提取某个商品销售的数量,那么就可以使用Count,如果想要知道销售的平均价格,那么就可以使用Avg. 聚合函数是通过aggregat ...

  9. Django(18)聚合函数

    前言 orm模型中的聚合函数跟MySQL中的聚合函数作用是一致的,也有像Sum.Avg.Count.Max.Min,接下来我们逐个介绍 聚合函数 所有的聚合函数都是放在django.db.models ...

随机推荐

  1. 【BZOJ 3561】 DZY Loves Math VI

    题目: 给定正整数n,m.求   题解: 水题有益身心健康.(博客园的辣鸡数学公式) 其实到这我想强上伯努利数,然后发现$n^2$的伯努利数,emmmmmm 发现这个式子可以算时间复杂度,emmmmm ...

  2. BZOJ_3629_[JLOI2014]聪明的燕姿_dfs

    BZOJ_3629_[JLOI2014]聪明的燕姿_dfs Description 阴天傍晚车窗外 未来有一个人在等待 向左向右向前看 爱要拐几个弯才来 我遇见谁会有怎样的对白 我等的人他在多远的未来 ...

  3. [Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树

    分析: Dijkstra求最短路树,在最短路树上进行操作,详情可见上一篇博客:http://www.cnblogs.com/Winniechen/p/9042937.html 我觉得这个东西不压行写出 ...

  4. jdk源码剖析一:OpenJDK-Hotspot源码包目录结构

    开启正文之前,先说一下源码剖析这一系列,就以“死磕到底”的精神贯彻始终,JDK-->JRE-->JVM(以openJDK代替) 最近想看看JDK8源码,但JDK中JVM(安装在本地C:\P ...

  5. Android 8.1 源码_启动篇(二) -- 深入研究 zygote(转 Android 9.0 分析)

    前言 在Android中,zygote是整个系统创建新进程的核心进程.zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态.在之后的运作中,当其他 ...

  6. 系统的讲解 - SSO单点登录

    目录 概念 好处 技术实现 小结 扩展 概念 SSO 英文全称 Single Sign On,单点登录. 在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统. 比如:淘宝网(www.t ...

  7. SpringBoot进阶教程(二十八)整合Redis事物

    Redis默认情况下,事务支持被禁用,必须通过设置setEnableTransactionSupport(true)为使用中的每个redistplate显式启用.这样做会强制将当前重新连接绑定到触发m ...

  8. Go:学习笔记兼吐槽(1)

      Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 自动添加分号 在很多其他的编程语言中,每一行代码的结尾都必须有分号(假设一行中只有一句代码),Golang 的开 ...

  9. 程序员如何巧用Excel提高工作效率

    作为一名程序员,我们可能很少使用Excel,但是公司的一些职能部门,比如HR,财务等,使用Excel真的是太熟练了,以至于一些系统开发出来,导入和导出功能是使用最频繁的,哈哈. 其实在程序开发的过程中 ...

  10. Django Admin管理入门

    Django最强大的部分之一是自动管理界面.它从模型中读取元数据,以提供快速,以模型为中心的界面,受信任的用户可以在其中管理您网站上的内容.管理员的推荐用途仅限于组织的内部管理工具.它不是用于构建整个 ...