count(1)比count(*)效率高?

SELECT COUNT(*) FROM table_name是个再常见不过的统计需求了。
本文带你了解下 MysqlCOUNT函数。

一、 COUNT 函数

关于 COUNT函数,在 MySQL官网中有详细介绍

count(1)比count(*)效率高?

翻译一下:

  1. COUNT(expr) ,返回 SELECT语句检索的行中 expr的值不为 NULL的数量,结果是一个 BIGINT值。
  2. 如果查询结果没有命中任何记录,则返回 0
  3. COUNT(*) 的统计结果中,会包含值为 NULL的行数。

《阿里巴巴Java开发手册》也有如下要求:

count(1)比count(*)效率高?

二、 COUNT(列名)COUNT(常量)COUNT(*)

前面我们提到过 COUNT(expr)用于做行数统计,那么 COUNT(列名)COUNT(常量)COUNT(*)这三种语法中, expr分别是列名、 常量 和 *

2.1 COUNT(*)COUNT(常量)

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

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

2.2 COUNT(*)COUNT(1) 区别

COUNT(1)就是 COUNT(常量),对于这二者到底有没有区别:

  1. 有的说 COUNT(*)执行时会转换成 COUNT(1),所以 COUNT(1)少了转换步骤,所以更快。
  2. 还有的说,因为 MySQL针对 COUNT(*)做了特殊优化,所以 COUNT(*)更快。

到底哪种说法是对的?看下 MySQL官方文档:

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

通过文档,对于 COUNT(1)COUNT(*)MySQL的优化是完全一样的,根本不存在谁比谁快!

2.3 COUNT(列名)

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

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

2.4 SQL92

除了查询得到结果集有区别之外, COUNT(*)相比 COUNT(常量)COUNT(列名)来讲, COUNT(*)SQL92定义的标准统计行数的语法,因为他是标准语法,所以 MySQL数据库对他进行过很多优化。

SQL92,是数据库的一个 ANSI/ISO标准。它定义了一种语言( SQL)以及数据库的行为(事务、隔离级别等)。

2.5 COUNT(*) 优化

因为 COUNT(*)SQL92定义的标准统计行数的语法,所以 MySQL对其进行了很多优化:

  1. MyISAM中会直接把表的总行数单独记录下来供 COUNT(*)查询
  2. InnoDB会在扫表的时候选择最小的索引来降低成本。

这些优化的前提都是没有进行 wheregroup的条件查询,更多请参考MySQL 全表 COUNT(*) 简述

三、总结

COUNT函数用于统计表行数,按照效率比较的话:

count(*)=count(常量)>count(列名)

3.1 小建议

既然 count(*) 在查询上依赖于所有的数据集,所以我们在设计上也需要尽量的规避全量 count

通常情况我们针对 可预见count 查询会做适当的缓存,可以是 Redis,也可以是独立的 MySQL count 表。

3.2 技术交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. Github

Original: https://www.cnblogs.com/VanFan/p/12248605.html
Author: 风尘博客
Title: count(1)比count(*)效率高?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/573578/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 头秃了,二十三张图带你从源码了解Spring Boot 的启动流程~

    前言 源码版本 从哪入手? 源码如何切分? 如何创建SpringApplication? 设置应用类型 设置初始化器(Initializer) 设置监听器(Listener) 设置…

    Java 2023年6月14日
    092
  • idea自动补全代码及scanner方法快捷键

    1.Shift+Enter: 不管鼠标位置在哪都能向下插入一行。 适合场景:修改刚写完的某条语句的某个地方之后,不需要用鼠标点到语句最后再回车,直接Shift+Enter接着往下打…

    Java 2023年6月9日
    0122
  • Java的三大特性

    Java的三大特性 封装: 隐藏内部功能的具体实现,只保留和外部交流数据的接口,将变化隔离,便于使用,提高复用性和安全性。例:汽车与发动机,不必知道发动机的实现原理,只需使用汽车给…

    Java 2023年6月13日
    068
  • Java线程数过多解决之路——利用Arthas解决Jenkins线程数飙升问题

    背景 Jenkins是基于Java开发的一款持续集成工具,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。同时,Jenkins 提供了数量庞大的各种插 件,以满足用户对…

    Java 2023年6月9日
    0126
  • Virtualbox下利用host-only连接方式实现虚拟机和物理机联网(包括wifi)

    https://blog.csdn.net/wordsin/article/details/80738262?utm_medium=distribute.pc_relevant_t…

    Java 2023年5月30日
    087
  • 数据库备份脚本

    #!/bin/bash #备份文件目录 backDir="/data/log/mysql/" if [ ! -d "$backDir" ];…

    Java 2023年6月8日
    079
  • (转)Math.Round() — c# 与 java的区别

    明明知道,java与c#在很多方面都有很多不同,但是如果让详细描述,却不一定能说出来多少。 前段时间碰见一个问题,才恍然大悟般的,明白了一条不同。 有同事的同学笔试,有道题目是 M…

    Java 2023年5月29日
    0101
  • Drools 规则引擎应用 看这一篇就够了

    1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ………

    Java 2023年6月7日
    073
  • SpringBoot中配置Logback日志输出

    因为在SpringBoot中默认使用的Logback日志系统,所以SpringBoot已经集成了相关依赖,无需多余的依赖,只需在src/main/resources文件夹下,增加l…

    Java 2023年5月30日
    074
  • 频频曝出程序员被抓,我们该如何避免面向监狱编程?

    过去几年,频频有程序员被抓的消息刷爆技术圈,无论是技术高手、公司合伙人还是普通程序员,甚至整个科技公司,都有因为违法被抓的案例。 案例 比如: 1、著名的Nignx之父Igor S…

    Java 2023年5月29日
    075
  • 实现线程的两种方式

    实现Runnable接口如果当前类 不仅要继承其他类( 非Thread类), 还要实现多线程,那么 只能通过当前类实现 Runnable接口来 创建Thread类对象。 实现Run…

    Java 2023年6月9日
    087
  • 木头人の狂想

    我看见太阳,它很热我看见天空,它很蓝我看见湖水,它很清我看见风,它兴高采烈我看见垂柳,它正随风一起跳舞 太阳问,我如此绚烂,为何你却感觉不到温暖?心在黑夜 你未曾照耀 天空问,如此…

    Java 2023年6月5日
    078
  • springboot整合ehcache

    springboot整合ehcache 工具类实现缓存 1. jar包导入 <dependency>   <groupId>org.springf…

    Java 2023年6月9日
    067
  • 云原生系列6 基于springcloud架构风格的本地debug实现

    debug是程序员在日常开发中最常使用的操作, 那么,你是如何快速在微服务架构风格下快速debug后端服务呢? 开发现状 开发的理想状态 本地调测的使用步骤 登录智能网关 如果集成…

    Java 2023年6月8日
    079
  • 复制pom文件内容时,所报的错

    一、错误提示 Non-parseable POM D:\kettleWebDemo\pom.xml: expected START_TAG or END_TAG not TEXT …

    Java 2023年6月9日
    072
  • 5 信息的表示和处理_整数表示

    1 无符号数编码 2 补码编码 3 有符号数和无符号数之间的转换 3.1 补码转为无符号数 3.2 无符号数转为补码 4 数字的位扩展 5 数字的位截断 6 C跟Java对无符号数…

    Java 2023年6月7日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球