count返回0_MySQL实战 | 14 为什么count(*)越来越慢?

25312a330db419ac12c0172d349a3d61.png

select count(*) 应该是一个比较常用的语句,用来统计记录行数。

但是,慢慢地你会发现,这个语句越来越慢了,为什么呢?

count(*) 的实现方式

首先,我们来看下它的实现方式。

MySQL 中,不同的存储引擎,count(*) 的实现方式是不同的。

1、MyISAM 引擎,比较简单粗暴,直接将表的总行数存储在磁盘上,因此效率很高;

2、InnoDB 引擎中,执行时,需要一行行的把数据查出来,然后累加;

为啥 MyISAM 就可以这样做呢?因为它不支持事务啊,不用担心数据不一致的问题。

而 InnoDB 就不一样了。

由于 MVCC 的存在,InnoDB 在当前执行环境下,对一共有多少数据行是不确定的,比如:

假设,表 t 中有 1000 条数据,有下面三个用户并行的会话:

1、A 启动事务,查询表的总行数;

2、C 直接插入一条数据,然后查询总行数;

3、B 启动事务,插入一条数据,然后查询总行数;

4、C 查询总行数;

注意,上面启动的事务都没有提交。

74d0e4b83b8f3fbdb8151614291e600a.png

image

A、B、C 查询的结果都不相同。

B 读到的是 1002,是因为可重复读隔离级别的存在,而 C 未开启事务,因此无法看到别的事务的更新;

综上,InnoDB 引擎中,在每一个会话中,都需要逐行读取数据,然后计数返回总行数。

InnoDB 对 count(*) 的优化

InnoDB 中,主键索引存储的是数据,辅助索引存储的只是主键值。

因此,辅助索引比主键索引小得多,轻量得多。

这种情况下,InnoDB 在执行 count(*) 时,就会判断使用哪个索引,会选择最小的树来进行遍历。

在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

小结

1、由于 MyISAM 引擎不需要支持事务,因此可以快速返回 count(*);

2、show table status 命令虽然返回很快,但是不准确;

3、InnoDB 执行 count(*) 时会遍历全表,因此性能较差;

count(*)、count(1)、count(主键)、count(字段)的区别

以下,基于 InnoDB。

含义区别

count() 是一个聚合函数,对于返回的结果集,会逐行判断,若返回的不是 NULL,就会加 1,否则不加。

因此,count(*)、count(主键 id) 和 count(1) 都表示返回满足条件的结果集的总行数;而 count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数。

性能区别

分析性能,考虑以下几个原则:

1、server 层要什么就会返回什么;

2、InnoDB 只返回必要的值;

3、优化器只优化了 count(*)

对于 count(主键id),InnoDB 会遍历全表,取每行的主键 id,返回给 server 层,server 层拿到数据后,进行判断累加。

对于 count(1),InnoDB 仍遍历全表,但是不取值,server 层对返回的每一行数据新增一个 1,然后进行判断累加;

因此,count(1) 要更快些,因为无需取值。从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。

对于 count(字段):

1、如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;2、如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。

但是 count(*) 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加。

结论:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)。

作者:hoxis
链接:https://www.jianshu.com/p/40b6ead97aa0
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql info commit_mysql show processlist 发现大量的commit

今天执行show processlist 发现大量的commit&#xff1b;查看锁信息&#xff0c;发现基本上都是-----------------------------------------------------------------------------------------------------------------------------------------------------------------------…

sql管理:索引超出范围必须为非负值并小于集合大小_java面试基础知识-数据库基础知识(数据库索引部分)...

1.1数据库架构&#xff1a;如何设计一个关系型数据库?存储模块&#xff08;文件系统&#xff09;用块或者页作为存储单位 程序实例&#xff1a;存储管理缓存机制 不宜过大&#xff0c;要有淘汰机制SQL解析日志管理权限划分容灾机制索引管理锁管理1.2 索引为什么要使用索引&…

今日头条 mysql_今日头条的核心架构解析

一、产品背景今日头条是为用户提供个性化资讯客户端。下面就和大家分享一下当前今日头条的数据(据内部与公开数据综合)&#xff1a;5亿注册用户2014年5月1.5亿&#xff0c;2015年5月3亿&#xff0c;2016年5月份为5亿。几乎为成倍增长。日活4800万用户2014年为1000万日活&#x…

编译原理语法分析_斯坦福大学《编译原理》学习记录 - 第二章:语法分析器

05-01: Introduction to Parsing 语法分析parser的作用&#xff1a;05-02: Context Free Grammars 上下文无关文法CFG&#xff08;上下文无关文法&#xff09;回答了一个字符串是否属于某语言&#xff1a;CFG的组成&#xff1a;终止符非终止符开始符生成式生成式production &am…

mysql中 视图的优缺点_数据库视图优缺点分析

视图作用是什么所谓视图(View)其实是执行查询语句后得到的结果&#xff0c;但这个查询结果可以仿真成数据表来使用&#xff0c;所以有人也称它为“虚拟数据表”&#xff0c;视图在操作上和数据表没有什么区别&#xff0c;但两者的差异是其本质是不同的&#xff1a;数据表是实际…

mysql永远不用utf8_永远不要在 MySQL 中使用「utf8」

题图&#xff1a;by apple from Instagram本文出自极客邦「聊聊架构」公众号的编译。我自己当年也被这个问题坑过&#xff0c;当时并没有如此详细的分析文章。我觉得有责任再次分享一下&#xff0c;让更多人知道这个事情。程序员不帮助程序员&#xff0c;还能指望谁呢&#xff…

sqoop mysql parquet_Sqoop抽取Hive Parquet表数据到MySQL异常分析

温馨提示&#xff1a;要看高清无码套图&#xff0c;请使用手机打开并单击图片放大查看。Fayson的github&#xff1a;https://github.com/fayson/cdhproject1.问题描述在CDH集群中我们需要将Hive表的数据导入到RDBMS数据库中&#xff0c;使用Sqoop工具可以方便的将Hive表数据抽取…

mysql按select导出_mysql 导出select结果到文本的几种方式

mysql -hxx -uxx -pxx -e "query statement" db > file例如&#xff1a;mysql -h127.0.0.1 -uroot -p000000 -e"select * from a" test > 1.txthost ip user password query statement database filename这样会输出列名信息&#xff0c;如…

mysql架设_主从mysql架设

主从mysql架设二进制安装mysqltar xvf mysql-5.1.46-linux-i686-glibc23.tar -C /usr/localcd /usr/localln -sv mysql-5.1.46-linux-i686-glibc23.tar mysqlcd mysqlgroupadd mysqluseradd -g mysql -s /sbin/nologin -M -r mysqlmkdir /mysql/datachown -R mysql.mysql /mysq…

日志文件和mysql同步到kafka_logstash_output_kafka:Mysql 同步 Kafka 深入详解

0、题记实际业务场景中&#xff0c;会遇到基础数据存在 Mysql 中&#xff0c;实时写入数据量比较大的情景。迁移至kafka是一种比较好的业务选型方案。而mysql写入kafka的选型方案有&#xff1a;方案一&#xff1a;logstash_output_kafka 插件。方案二&#xff1a;kafka_connect…

mysql max嵌套select_使用嵌套select子式 解决mysql不能叠加使用如max(sum())的问题

网上也有解决方案 有的有瑕疵 有的较复杂(mysql没有分析函数&#xff0c;可以使用变量实现) select sumScoreValue,studentid,studentName from sc_studentb, ( select sum (scoreValue) as sumScoreValue,studentid from sc_score group by studentid order by sumSc网上也有解…

mysql 检查记录存在_Mysql 插入记录时检查记录是否已经存在,存在则更新,不存在则插入记录SQL...

我们在开发数据库相关的逻辑过程中&#xff0c; 经常检查表中是否已经存在这样的一条记录&#xff0c; 如果存在则更新或者不做操作&#xff0c; 如果没有存在记录&#xff0c;则需要插入一条新的记录。这样的逻辑固然可以通过两条sql语句完成。SELECT COUNT(*) FROM xxx WHERE…

python linux调试_python调试

以下是我做调试或分析时用过的工具的一个概览。如果你知道有更好的工具&#xff0c;请在评论中留言&#xff0c;可以不用很完整的介绍。日志没错&#xff0c;就是日志。再多强调在你的应用里保留足量的日志的重要性也不为过。你应当对重要的内容打日志。如果你的日志打的足够好…

猜数字游戏python程序用函数guesssecret_Python-三、函数

3.1 def语句和参数def ...(...)语句用于定义一个函数&#xff0c;以便后面调用函数&#xff0c;如&#xff1a;def hello(name): #定义函数hello&#xff0c;变元nameprint(hello name) #打印hello变元namenamein input() #定义namein变量&#xff0c;从键盘取值并赋给namein…

java 命令行参数 _java命令行参数

原标题&#xff1a;java命令行参数命令行参数就是main方法里面的参数String[] args他就是一个数组&#xff0c;args只是数据类型的一个名称&#xff0c;就是一个数组的变量&#xff0c;名称无所谓&#xff0c;类型没变就行了。这个就是程序的入口点。如图7.4所示&#xff1a;图…

java 最小生成树_图的最小生成树(java实现)

1.图的最小生成树(贪心算法)我两个算法的输出都是数组表示的&#xff0c;当前的索引值和当前索引对应的数据就是通路&#xff0c;比如parent[2] 5;即2和5之间有一个通路&#xff0c;第二个可能比较好理解&#xff0c;第一个有点混乱是什么&#xff1f;将一个有权图中的 所有顶…

中文分词工具 java_java读取中文分词工具(一)

import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.RandomAccessFile;import java.util.StringTokenizer;/** 文本格式&#xff1a;已分词的中文文本&#xff0…

java中的成员变量和局部变量的区别_java中成员变量与局部变量区别分析

本文实例分析了java中成员变量与局部变量区别。分享给大家供大家参考。具体分析如下&#xff1a;成员变量&#xff1a;在这个类里定义的私有变量&#xff0c;属于这个类。创建以及使用成员变量public class Person {String name;String Sex;int age;double Height;public stati…

java 自定义注解 生成json_用自定义注解实现fastjson序列化的扩展

这篇文章起源于项目中一个特殊的需求。由于目前的开发方式是前后端分离的&#xff0c;基本上是通过接口提供各个服务。而前两天前端fe在开发中遇到了一些问题&#xff1a;他们在处理字符串类型的时间时会出现精度丢失的情况&#xff0c;所以希望后台是以时间戳的形式返回给前端…

工厂模式 java场景_研磨设计模式之简单工厂模式(场景问题)

简单工厂不是一个标准的设计模式&#xff0c;但是它实在是太常用了&#xff0c;简单而又神奇&#xff0c;所以还是需要好好掌握的&#xff0c;就当是对学习设计模式的热身运动吧。为了保持一致性&#xff0c;我们尽量按照学习其它模式的步骤来进行学习。1 场景问题大家都知道&…