MySQL数据库统计函数COUNT的使用及说明

 更新时间:2024年07月18日 17:01:02   作者:谈谈1974  
这篇文章主要介绍了MySQL数据库统计函数COUNT的使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. COUNT 函数的作用

数据库系统中 COUNT(expr)用于统计数据行数,其主要作用为返回SELECT语句检索的行中 expr 表达式的值不为 NULL 的行的数量,返回值是一个 BIGINT 值,如果查询结果没有命中任何记录则返回 0。

通常的使用方式主要有以下两种:

  • COUNT(column) 表示统计对应列有值(不为空)的数据的行数
  • COUNT(*) 表示统计结果集的总行数

2. COUNT(*) 与 COUNT(1) 与 COUNT(column)

COUNT(expr)统计的是 expr 不为 NULL的行数,而在COUNT(column)COUNT(1)COUNT(*)三种用法中,expr 分别是列名常量*

这三个条件中常量是一个固定值,肯定不为NULL。

*可以理解为查询整行,所以肯定也不为NULL,只有列名的查询结果有可能是NULL。

故 COUNT(1) 和 COUNT(*) 可认为是直接查询符合条件的数据库表的行数,而COUNT(column)表示的是查询符合条件的列的值不为NULL的行数。

  • 对于COUNT(1)和COUNT(*),官方的说法是在 InnoDB 引擎中二者完全一样,不存在快慢区别
  • COUNT(column)的查询则比较简单粗暴,就是进行全表扫描,然后判断指定字段的值是不是为NULL,不为NULL则累加

相比 COUNT(*),COUNT(column) 多了一个判断所查询的字段是否为 NULL 的步骤,所以效率要比 COUNT(*) 低

3. MySQL 对 COUNT 的优化

这些优化的前提都是查询语句中不包含 WHERE 及 GROUP BY 限定条件

3.1 MyISAM 引擎优化

MyISAM 引擎的锁是表级锁,同一张表上的操作都是串行完成,故MyISAM做了一个简单的优化,就是把表的总行数单独记录下来

使用 COUNT(*) 查询表的总行数时,直接返回这个记录下来的数值就可以了,当然前提是不能有where条件

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

3.2 InnoDB 引擎优化

因为 InnoDB 支持事务,其中大部分操作都是行级锁,所以表的行数可能会被并发修改,在这种情况下将总行数记录下来的方式就不准确了。

因此 InnoDB 中使用 COUNT( * ) 查询行数的时候,不可避免地要进行扫表,只能在扫表过程中来优化效率

我们知道,InnoDB 中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引)聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值。

COUNT(*)只是为了统计总行数,不用关心查到的具体值,如果在扫表的过程中选择一个成本较低的索引的话,那就可以大大节省时间。

显而易见,非聚簇索引要比聚簇索引小很多,所以 InnoDB 引擎会优先选择最小的非聚簇索引来扫表。

根据这个特性可知,建表的时候除了主键索引以外,创建一个非主键索引也很有必要

4. COUNT 查询优化

假设有一张表t_user,里面有大概5000条记录,一个需求是统计 id 大于 20 的用户数量,以下两种写法效率大不相同

简单的条件查找,近乎扫描全表,表较小时效率很高,表数据较多就很耗时

SELECT
    count( * ) 
FROM
    t_user
WHERE
    id > 20;

另一个思路是先统计 id 小于 20 的记录,再使用总的行数减去该值就得到了结果。

这是因为查询优化阶段会把该类子查询当作常数处理,只需扫描 id < 20 的行,开销大幅减少

SELECT
    ( SELECT COUNT( * ) FROM t_user ) - count( * ) 
FROM
    t_user 
WHERE
    id < 20;

总结

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

相关文章

  • 解决mysql与navicat建立连接出现1251错误

    解决mysql与navicat建立连接出现1251错误

    在本篇文章里小编给大家整理了一篇关于mysql与navicat建立连接出现1251错误怎么解决的技术文章,需要的朋友们参考下。
    2019-08-08
  • MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理

    MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理

    这篇文章主要介绍了MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-08-08
  • mysql根据拼音字母查询(简单易懂的字段拼音查询)

    mysql根据拼音字母查询(简单易懂的字段拼音查询)

    MySQL在开发中,我们经常需要根据字段拼音查询数据库中的数据,它支持多种查询方式,包括根据拼音字母查询,使用 Collation 可以方便地进行简单的拼音查询,而使用拼音索引可以大幅提高查询性能,根据具体的需求和情况,我们可以选择合适的方法来实现拼音查询
    2023-10-10
  • Centos7下安装和配置MySQL5.7.20的详细教程

    Centos7下安装和配置MySQL5.7.20的详细教程

    这篇文章主要介绍了Linux(CentOS7)下安装和配置MySQL5.7.20详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价,需要的朋友可以参考下
    2020-05-05
  • MySql索引的作用以及对索引的理解

    MySql索引的作用以及对索引的理解

    这篇文章主要给大家介绍了关于MySql索引的作用以及对索引的理解,MySQL索引的建立对于MySQL的高效运行是很重要的,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • MySQL动态创建表,数据分表的存储过程

    MySQL动态创建表,数据分表的存储过程

    MySQL动态创建表,数据分表的存储过程,需要的朋友可以参考下。
    2011-08-08
  • Mysql systemctl start mysqld报错的问题解决

    Mysql systemctl start mysqld报错的问题解决

    最近运行Mysql发现报错,本文就来介绍一下Mysql systemctl start mysqld报错的问题解决,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06
  • MySQL查看和修改字符编码的实现方法

    MySQL查看和修改字符编码的实现方法

    下面小编就为大家带来一篇MySQL查看和修改字符编码的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • mysql存储过程原理与使用方法详解

    mysql存储过程原理与使用方法详解

    这篇文章主要介绍了mysql存储过程原理与使用方法,结合实例形式详细分析了mysql存储过程的优缺点、定义、调用方法及相关操作注意事项,需要的朋友可以参考下
    2019-12-12
  • Mysql8报错this is incompatible with sql_mode=only_full_group_by问题

    Mysql8报错this is incompatible with sql_mo

    这篇文章主要介绍了Mysql8报错this is incompatible with sql_mode=only_full_group_by问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01

最新评论