关于sql count(列名)、count(常量)、count(*)之间的区别

 更新时间:2023年08月29日 09:00:45   作者:紫金小飞侠  
这篇文章主要介绍了关于sql count(列名)、count(常量)、count(*)之间的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

COUNT(列名)、COUNT(常量)和COUNT(*)之间的区别

COUNT( * )和COUNT(1) :在InnoDB中COUNT(*)和COUNT(1)实现上没有区别,而且效率一样,统计结果中,会包含值为NULL的行数COUNT(字段): 需要进行字段的非NULL判断,所以效率会低一些。

因为COUNT( * )是SQL92定义的标准统计行数的语法,并且效率高,所以没有某个字段不为null 的统计行数需求请直接使用COUNT( * )查询表的行数!

COUNT(id)和COUNT()以外,还可以使用COUNT(常量)(如COUNT(1))来统计行数,那么这三条SQL语句有什么区别呢?

到底哪种效率更高呢?

为什么《阿里巴巴Java开发手册》中强制要求不让使用 COUNT(列名)或 COUNT(常量)来替代 COUNT()呢?

在这里插入图片描述

1、COUNT(列名) ,返回SELECT语句检索的行中expr的值不为NULL的数量。结果是一个BIGINT值。

2、但是,值得注意的是,COUNT( * ) 和count(1)的统计结果中,会包含值为NULL的行数。

那么列名、 常量 和 *这三个条件中,常量 是一个固定值,肯定不为NULL。*可以理解为查询整行,所以肯定也不为NULL,那么就只有列名的查询结果有可能是NULL了。

所以, COUNT(常量) 和 COUNT( * )表示的是直接查询符合条件的数据库表的行数。而COUNT(列名)表示的是查询符合条件的列的值不为NULL的行数。

COUNT(*)是SQL92定义的标准统计行数的语法,因为他是标准语法,所以MySQL数据库对他进行过很多优化。

COUNT(*)和COUNT(1)

COUNT(*)和COUNT(1)这二者到底有没有区别,网上的说法众说纷纭。

有的说COUNT(*)执行时会转换成COUNT(1),所以COUNT(1)少了转换步骤,所以更快。

还有的说,因为MySQL针对COUNT()做了特殊优化,所以COUNT()更快。

那么,到底哪种说法是对的呢?

看下MySQL官方文档是怎么说的:

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

画重点:

same way , no performance difference。

所以,对于COUNT(1)和COUNT(*),MySQL的优化是完全一样的,根本不存在谁比谁快!

COUNT( * )和COUNT(字段)

COUNT(字段),他的查询就比较简单粗暴了,就是进行全表扫描,然后判断指定字段的值是不是为NULL,不为NULL则累加。

相比COUNT(),COUNT(字段)多了一个步骤就是判断所查询的字段是否为NULL,所以他的性能要比COUNT()慢。

COUNT(*)的优化

MySQL中比较常用的执行引擎就是InnoDB和MyISAM。

MyISAM

不包含WHERE或GROUP BY等条件

MyISAM不支持事务,MyISAM中的锁是表级锁;而InnoDB支持事务,并且支持行级锁。

因为MyISAM的锁是表级锁,所以同一张表上面的操作需要串行进行,所以,MyISAM做了一个简单的优化,那就是它可以把表的总行数单独记录下来,如果从一张表中使用COUNT(*)进行查询的时候,可以直接返回这个记录下来的数值就可以了,当然,前提是不能有where条件。

MyISAM之所以可以把表中的总行数记录下来供COUNT(*)查询使用,那是因为MyISAM数据库是表级锁,不会有并发的数据库行数修改,所以查询得到的行数是准确的。

InnoDB

不包含WHERE或GROUP BY等条件

InnoDB来说,就不能做这种缓存操作了,因为InnoDB支持事务,其中大部分操作都是行级锁,所以可能表的行数可能会被并发修改,那么缓存记录下来的总行数就不准确了。

InnoDB中索引分为主键索引和非主键索引主键引的叶子节点中保存的是整行记录,而非主键索引的叶子节点中保存的是该行记录的主键的值。

所以,相比之下,非主键索引要比主键索引小很多,所以MySQL会优先选择最小的非主键索引来扫表。所以,当我们建表的时候,除了主键索引以外,创建一个非主键索引还是有必要的。

count(*)、count(列名)、count(常量)的理解

内容来之阿里巴巴的开发手册:

1.  【强制】不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的

标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。

说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

2.  【强制】count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为 0。

3.  【强制】当某一列的值全是 NULL 时,count(col)的返回结果为 0,但 sum(col)的返回结果 为 NULL,因此使用 sum()时需注意 NPE 问题。

正例:使用如下方式来避免 sum 的 NPE 问题:SELECT IFNULL(SUM(column), 0) FROM table;

4.  【强制】使用 ISNULL()来判断是否为 NULL 值。

说明:NULL 与任何值的直接比较都为 NULL。

1) NULL<>NULL 的返回结果是 NULL,而不是 false。

2) NULL=NULL 的返回结果是 NULL,而不是 true。

3) NULL<>1 的返回结果是 NULL,而不是 true。

如何在同一个查询中统计同,一个列的不同值的数量,以减少查询的语句量。

例如:

通过一个查询返回各种不同颜色的商品数量 。

select count(color='blue' or color='red') from items; (不满足条件,因为无法区分不同颜色的商品数量)
select count(*) from items where color = 'blue' and color = 'red';(不满足条件,颜色的条件是互斥的)

下面为满足条件的例子:

select sum(if(color = 'blue', 1, 0)) as blue, sum(if(color = 'red', 1, 0)) as red from items;
select count(color = 'blue' or NULL) as blue, count(color = 'red' or NULL) as red from items;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 安装MySQL在最后的start service停住了解决方法

    安装MySQL在最后的start service停住了解决方法

    今天为一个客户配置服务器的时候,发现的问题,原来他自己安装过mysql但安全没有配置好,路径选择的也不好,重新安装后发现在start service卡住了,通过下面的方法解决了,特分享下
    2013-11-11
  • 关于Mysql提高SQL性能的技巧(必看)

    关于Mysql提高SQL性能的技巧(必看)

    这篇文章主要介绍了关于Mysql提高SQL性能的技巧(必看),SQL查询的性能直接影响系统的响应时间,优化SQL可以减少查询的执行时间,提高系统的响应速度,提升用户体验,本文就来详细讲解一下如何优化SQL性能
    2023-07-07
  • 设置MySQL中的数据类型来优化运行速度的实例

    设置MySQL中的数据类型来优化运行速度的实例

    这篇文章主要介绍了设置MySQL中索引的数据类型来优化运行速度的实例,主要是适当使用短字节的数据类型来处理短索引,需要的朋友可以参考下
    2015-05-05
  • MySQL Order by 语句用法与优化详解

    MySQL Order by 语句用法与优化详解

    Order by语句是用来排序的,经常我们会使用到Order by来进行排序,下面我给大家来讲讲Order by用法与优化排序,有需要的同学可参考
    2013-06-06
  • 深入mysql外键关联问题的详解

    深入mysql外键关联问题的详解

    本篇文章是对mysql外键关联问题进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL多表查询的具体实例

    MySQL多表查询的具体实例

    这篇文章主要介绍了MySQL多表查询的具体实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • MYSQL 一个巧用字符函数做数据筛选的题

    MYSQL 一个巧用字符函数做数据筛选的题

    这篇文章主要介绍了MYSQL 一个巧用字符函数做数据筛选的题,需要的朋友可以参考下
    2017-05-05
  • 如何修改Xampp服务器上的mysql密码(图解)

    如何修改Xampp服务器上的mysql密码(图解)

    如果我们使用Xampp服务器自带数据库mysql,就必须先修改mysql的密码,下面小编给大家分享如何修改Xampp服务器上的mysql密码,需要的朋友参考下吧
    2017-04-04
  • MySQL总是差八个小时该如何解决

    MySQL总是差八个小时该如何解决

    最近在用mybatis时发现,将LocalDateTime插入到数据库时时间少了8小时,下面这篇文章主要给大家介绍了关于MySQL总是差八个小时该如何解决的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • mysql5.7.19 winx64安装配置方法图文教程(win10)

    mysql5.7.19 winx64安装配置方法图文教程(win10)

    这篇文章主要为大家详细介绍了mysql5.7.19 winx64安装配置教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07

最新评论