SELECT COUNT(*) 底层究竟干了啥么?

Select count(*)、Count(1)和Count(列)的区别及执行方式 在SQL Server中Count(*)或者Count(1)或者Count([列])或许是最常用的聚合函数。很多人其实对这三者之间是区分不清的。本文会阐述这三者的作用,关系以及背后的原理。     往常我经常会看到一些所谓的优化建议不使用Count(* )而是使用Count(1),从而可以提升性能,给出的理由是Count( *)会带来全表扫描。而实际上如何写Count并没有区别。     Count(1)和Count(*)实际上的意思是,评估Count()中的表达式是否为NULL,如果为NULL则不计数,而非NULL则会计数。比如我们看代码1所示,在Count中指定NULL(优化器不允许显式指 立即下载

点击上方“芋道源码”,选择“设为星标”

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 8:55 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:blog.didiyun.com/index.php/2019/01/08/mysql-count

  • 一、InnoDB 全表 COUNT(*)

  • 二、数据结构

  • 三、MyISAM 全表 COUNT(*)

  • 四、几个问题


“SELECT COUNT( * ) FROM TABLE” 是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表的存储引擎,在此前提下,COUNT( * )操作的时间复杂度为 O(N),其中 N 为表的行数。

而 MyISAM 表中可以快速取到表的行数。这些实践经验的背后是怎样的机制,以及为什么需要/可以是这样,就是此文想要探讨的。

先来看一下概况,MySQL COUNT( * ) 在 2 种存储引擎中的部分问题:

下面就带着这些问题,以 InnoDB 存储引擎为主来进行讨论。

一、InnoDB 全表 COUNT(*)

主要问题:

1、执行过程是怎样的?

2、如何计算 count?影响 count 结果的因素有哪些?

3、count 值存在哪里?涉及的数据结构是怎样的?

4、为什么 InnoDB 只能通过扫表来实现 count( * )?(见本文最后的问题)

5、全表COUNT( * )作为 table scan 类型操作的一个 case,有什么风险?

6、COUNT(* )操作是否会像“SELECT * ”一样可能读取大字段涉及的溢出页?

1、执行框架 – 循环: 读取 + 计数?

1.1、基本结论:
  • 全表扫描,一个循环解决问题。

  • 循环内: 先读取一行,再决定该行是否计入 count。

  • 循环内是一行一行进行计数处理的。

1.2、说明:

简单 SELELCT-SQL 的执行框架,类比 INSERT INTO … SELECT 是同样的过程。

下面会逐步细化如何读取与计数 ( count++ ) 。

2、执行过程?

执行过程部分,分为 4 个部分:

(1)COUNT( * ) 前置流程: 从 Client 端发 SQL 语句,到 MySQL-Server 端执行 SELECT 之前,为后面的一些阐述做一铺垫。

(2)COUNT( * ) 流程: 简要给出代码层面的流程框架及 2 个核心步骤的重点调用栈部分。

(3)读取一行: 可见性及 row_search_mvcc 函数,介绍可见性如何影响 COUNT( * ) 结果。

(4)计数一行: Evaluate_join_record 与列是否为空,介绍计数过程如何影响 COUNT( * ) 结果。

如果读者希望直接看如何进行 COUNT( * ),那么也可以忽略 (1),而直接跳到 (2) 开始看。

2.1、COUNT( * ) 前置流程回忆 – 从 Client 端发 SQL 到 sub_select 函数

为了使看到的调用过程不太突兀,我们还是先回忆一下如何执行到 sub_select 函数这来的:

(1)MySQL-Client 端发送 SQL 语句,根据 MySQL 通信协议封包发送。

(2)Mysql-Server 端接收数据包,由协议解析出 command 类型 ( QUERY ) 及 SQL 语句 ( 字符串 ) 。

(3)SQL 语句经过解析器解析输出为 JOIN 类的对象,用于结构化地表达该 SQL 语句。

PS: 这里的 JOIN 结构,不仅仅是纯语法结构,而是已经进行了语义处理,粗略地说,汇总了表的列表 ( table_list )、目标列的列表 ( target_list )、WHERE 条件、子查询等语法结构。

在全表 COUNT( * )-case 中,table_list = [表“t”(别名也是“t”)],target_list = [目标列对象(列名为“COUNT( * )”)],当然这里没有 WHERE 条件、子查询等结构。

(4)JOIN 对象有 2 个重要的方法: JOIN::optimize(), JOIN::exec(),分别用于进行查询语句的优化 和 查询语句的执行。

  • join->optimize(),优化阶段 (稍后 myisam 下全表 count( * ) 操作会涉及这里的一点内容)。

  • join->exec(),执行阶段 ( 重点 ),包含了 InnoDB 下全表count( * ) 操作的执行流程。

(5)join->exec() 经过若干调用,将调用到 sub_select 函数来执行简单 SQL,包括 COUNT( * ) 。

(6)END of sub_select 。

2.2、COUNT( * ) 流程 ( 于 sub_select 函数中 )

上层的流程与代码是比较简单的,集中在 sub_select 函数中,其中 2 类函数分别对应于前面”执行框架”部分所述的 2 个步骤 – 读取、计数。先给出结论如下:

(1)读取一行:从相对顶层的 sub_select 函数经过一番调用,最终所有分支将调用到 row_search_mvcc 函数中,该函数就是用于从 InnoDB 存储引擎所存储的 B+-tree 结构中读取一行到内存中的一个 buf (uchar * ) 中,待后续处理使用。

这里会涉及行锁的获取、MVCC 及行可见性的问题。当然对 于 SELECT COUNT( * ) 这类快照读而言,只会涉及 MVCC 及其可见性,而不涉及行锁。详情可跳至“可见性与 row_search_mvcc 函数”部分。

(2)计数一行: 代码层面,将会在 evaluate_join_record 函数中对所读取的行进行评估,看其是否应当计入 count 中 ( 即是否要 count++ )。

简单来说,COUNT(arg) 本身为 MySQL 的函数操作,对于一行来说,若括号内的参数 arg ( 某列或整行 ) 的值若不是 NULL,则 count++,否则对该行不予计数。详情可跳至“ Evaluate_join_record 与列是否为空”部分。

这两个阶段对 COUNT( * )结果的影响如下: (两层过滤)

SQL 层流程框架相关代码摘要如下:

Q:代码层面,第一步骤(读取一行)有 2 个分支,为什么?

A: 从 InnoDB 接口层面考虑,分为 “读第一行” 和 “读下一行”,是 2 个不同的执行过程,读第一行需要找到一个 ( cursor ) 位置并做一些初始化工作让后续的过程可递归。

正如我们如果用脚本/程序来进行逐行的扫表操作,实现上就会涉及下面 2 个 SQL:

具体涉及到此例的代码,SQL 层到存储引擎层的调用关系,读取阶段的调用栈如下:(供参考)

我们可以看到,无论是哪一个分支的读取,最终都殊途同归于 row_search_mvcc 函数。

以上是对 LOOP 中的代码做一些简要的说明,下面来看 row_search_mvcc 与 evaluate_join_record 如何输出最终的 count 结果。

2.3、行可见性及 row_search_mvcc 函数

这里我们主要通过一组 case 和几个问题来看行可见性对 COUNT( * ) 的影响。

Q:对于“SELECT COUNT( * ) FROM t”或者“SELECT MIN(id) FROM t”操作,第一次的读行操作读到的是表 t 中 ( B+ 树最左叶节点 page 内 ) 的最小记录吗?( ha_index_first 为何也调用 row_search_mvcc 来获取最小 key 值?)

A: 不一定。即使是 MIN ( id ) 也不一定就读取的是 id 最小的那一行,因为也同样有行可见性的问题,实际上 index_read 取到的是 当前事务内语句可见的最小 index 记录。这也反映了前面提到的 join_read_first 与 join_read_next “殊途同归”到 row_search_mvcc 是理所应当的。

Q:针对图中最后一问,如果事务 X 是 RU ( Read-Uncommitted ) 隔离级别,且 C-Insert ( 100 ) 的完成是在 X-count( * ) 执行过程中 ( 仅扫描到 5 或 10 这条记录 ) 完成的,那么 X-count( * ) 在事务 C-Insert ( 100 ) 完成后,能否在之后的读取过程中看到 100 这条记录呢?

A: MySQL 采取”读到什么就是什么”的策略,即 X-count( * ) 在后面可以读到 100 这条记录。

2.4、evaluate_join_record 与列是否为空

Q:某一行如何计入 count?

A: 两种情况会将所读的行计入 count:

(1)如果 COUNT 函数中的参数是某列,则会判断所读行中该列定义是否 Nullable 以及该列的值是否为 NULL;若两者均为是,则不会计入 count,否则将计入 count。

  • e.g. SELECT COUNT(col_name) FROM t

  • col_name 可以是主键、唯一键、非唯一键、非索引字段

(2)如果 COUNT 中带有 * ,则会判断这部分的整行是否为 NULL,如果判断参数为 NULL,则忽略该行,否则 count++。

  • e.g-1. SELECT COUNT(*) FROM t

  • e.g-2. SELECT COUNT(B.*) FROM A LEFT JOIN B ON A.id = B.id

Q:特别地,对于 SELECT COUNT(id) FROM t,其中 id 字段是表 t 的主键,则如何?

A: 效果上等价于 COUNT( * )。因为无论是 COUNT( * ),还是 COUNT ( pk_col ) 都是因为有主键从而充分断定索取数据不为 NULL,这类 COUNT 表达式可以用于获取当前可见的表行数。

Q:用户层面对 InnoDB COUNT( * ) 的优化操作问题

A: 这个问题是业界熟悉的一个问题,扫描非空唯一键可得到表行数,但所涉及的字节数可能会少很多(在表的行长与主键、唯一键的长度相差较多时),相对的 IO 代价小很多。

相关调用栈参考如下:

二、数据结构

Q:count 值存储在哪个内存变量里?

A: SQL 解析后,存储于表达 COUNT( * ) 这一项中,((Item_sum_count*)item_sum)->count

如下图所示回顾我们之前“COUNT( * )前置流程”部分提到的 JOIN 结构。

即 SQL 解析器为每个 SQL 语句进行结构化,将其放在一个 JOIN 对象 ( join ) 中来表达。在该对象中创建并填充了一个列表 result_field_list 用于存放结果列,列表中每个元素则是一个结果列的 ( Item_result_field* ) 对象 ( 指针 ) 。

在 COUNT( * )-case 中,结果列列表只包含一个元素,( Item_sum_count: public Item_result_field ) 类型对象 ( name = “COUNT( * )”),其中该类所特有的成员变量 count即为所求。

三、MyISAM 全表 COUNT(*)

由于 MyISAM 引擎并不常用于实际业务中,仅做简要描述如下:

1、MyISAM-COUNT( * ) 操作是 O(1) 时间复杂度的操作。

2、每张 MyISAM 表中存放了一个 meta 信息-count 值,在内存中与文件中各有一份,内存中的 count 变量值通过读取文件中的 count 值来进行初始化。

3、SELECT COUNT( * ) FROM t 会直接读取内存中的表 t 对应的 count 变量值。

4、内存中的 count 值与文件中的 count 值由写操作来进行更新,其一致性由表级锁来保证。

5、表级锁保证的写入串行化使得,同一时刻所有用户线程的读操作要么被锁,要么只会看到一种数据状态。

四、几个问题

Q:MyISAM 与 InnoDB 在 COUNT( * ) 操作的执行过程在哪里开始分道扬镳?

  • 共性:共性存在于 SQL 层,即 SQL 解析之后的数据结构是一致的,count 变量都是存在于作为结果列的 Item_sum_count 类型对象中;返回给客户端的过程也类似 – 对该 count 变量进行赋值并经由 MySQL 通信协议返回给客户端。

  • 区别:InnoDB 的 count 值计算是在 SQL 执行阶段进行的;而 MyISAM 表本身在内存中有一份包含了表 row_count 值的 meta 信息,在 SQL 优化阶段通过存储引擎的标记给优化器一个 hint,表明该表所用的存储引擎保存了精确行数,可以直接获取到,无需再进入执行器。

Q:InnoDB 中为何无法向 MyISAM 一样维护住一个 row_count 变量?

A: 从 MVCC 机制与行可见性问题中可得到原因,每个事务所看到的行可能是不一样的,其 count( * ) 结果也可能是不同的;反过来看,则是 MySQL-Server 端无法在同一时刻对所有用户线程提供一个统一的读视图,也就无法提供一个统一的 count 值。

PS: 对于多个访问 MySQL 的用户线程 ( COUNT( * ) ) 而言,决定它们各自的结果的因素有几个:

(1)一组事务执行前的数据状态(初始数据状态)。

(2)有时间重叠的事务们的执行序列 (操作时序,事务理论表明 并发事务操作的可串行化是正确性的必要条件)。

(3)事务们各自的隔离级别(每个操作的输入)。

其中 1、2 对于 Server 而言都是全局或者说可控的,只有 3 是每个用户线程中事务所独有的属性,这是 Server 端不可控的因素,因此 Server 端也就对每个 COUNT( * ) 结果不可控了。

Q:InnoDB-COUNT( * ) 属 table scan 操作,是否会将现有 Buffer Pool 中其它用户线程所需热点页从 LRU-list 中挤占掉,从而其它用户线程还需从磁盘 load 一次,突然加重 IO 消耗,可能对现有请求造成阻塞?

A: MySQL 有这样的优化策略,将扫表操作所 load 的 page 放在 LRU-list 的 oung/old 的交界处 ( LRU 尾部约 3/8 处 )。这样用户线程所需的热点页仍然在 LRU-list-young 区域,而扫表操作不断 load 的页则会不断冲刷 old 区域的页,这部分的页本身就是被认为非热点的页,因此也相对符合逻辑。

PS: 个人认为还有一种类似的优化思路,是限定扫描操作所使用的 Buffer Pool 的大小为 O(1) 级别,但这样做需要付出额外的内存管理成本。

Q:InnoDB-COUNT( * ) 是否会像 SELECT * FROM t 那样读取存储大字段的溢出页(如果存在)?

A:否。 因为 InnoDB-COUNT( * ) 只需要数行数,而每一行的主键肯定不是 NULL,因此只需要读主键索引页内的行数据,而无需读取额外的溢出页。



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

兄弟,艿一口,点个赞!????

超声波清洗机拆解实录:从电路板到换能器,一文看懂内部构造(附高清图) 本文详细拆解了超声波清洗机的内部构造,从电路板设计到换能器工作原理,揭示了其核心技术。通过高清图片和详细分析,展示了功率放大电路、高频变压器及压电换能器等关键部件,为电子爱好者和维修技术人员提供了实用的故障诊断和元件二次利用指南。 阅读详情

相关推荐

【Cadence软件技巧集萃】从Capture到Allergo——分布演示从原理符号导出到网络表

Cadence软件功能多样、性能强大,但是使用起来颇费步骤,尤其是从原理图到网络表的导入步骤,没有经过上手实践还真不一定一次就能搞定哩。本文笔者用将分步演示:1、在Capture软件上绘制原理图;2、将原理图导出网络表;3、在Allergo软件上更新网络表;希望给予使用Cadence的读者有效的帮助1、本文简述了建立Capture项目的步骤,演示了调用元件符号库的方法,并绘制了电气原理图;2、针对加载元件封装库可能遇到的问题,做了排查步骤建议;

qq_33175704的博客 2537

一条select语句的执行原理

第一步:查询缓存 一、介绍 注意:MySQL8.0之后就抛弃了缓存功能。(因为查询缓存平均效率不高)MySQL8.0之前可通过query_cache_type参数开关查询缓存 当SQL开始执行时,Server会现在查询缓存中查找该SQL语句。之前性质过的语句及其结果会以key-value的形式缓存在内存中。遍历所有key,查找是否有和执行的SQL吻合的,如果查找到,则直接将结果返回给客户端;如果没有,就会进入到解析器阶段,且最终的执行结果会被存入缓存之中。 二、查询缓存效率不高的原因? 1、两..

I_m_j的博客 323

不只是CPU主频:深入解析英飞凌Aurix TC3xx各外设时钟树(CAN、以太网、Flash时序如何配置)

本文深入解析英飞凌Aurix TC3xx系列微控制器的外设时钟树配置,涵盖CAN、以太网和Flash时序的优化方法。通过详细分析时钟系统架构、关键外设配置及多外设协同设计策略,帮助工程师实现高性能汽车电子控制单元(ECU)开发。特别关注系统时钟的灵活配置与EMC优化技巧,提升系统实时性和可靠性。

weixin_29189373的博客 401

记一次记忆深刻的springcloudgateway网关调优

https://blog.youkuaiyun.com/nmjuzi/article/details/118415773 某项目某地方客户自己部署,客户压测只压单机scg,不过nginx。 网关在一个8G16核的服务器并发竟然只能到2000。 即使加了5个副本以后并发也只能到6000,其他接口都直接拒绝。 而且在压测时数据返回的过程中经常卡住。 一开始是考虑到是不是路由过多造成的,但是公司的项目路由大概有一千多条也没有这么拉跨,某地项目路由最多10条。 我们尝试把地方项目压测使用的路由order调为1,情况会好一

yygr的博客 5566

PSpice 导入 LTspice 仿真实验 --(如何解决PSpice模型无法使用的错误)

参考了网上第三方器件导入LTspice的博客和资料,不论是哪个公司下载的SPICE模型导入LTspice的方法都类似。如果遇到导入报错的情况可以先看一下报错提示,如果通过语法修改实现功能的则说明可以进行仿真,当然性能可能与官方给的模型存在一点出入,但做一个基本的功能验证本人认为还是可以的,总比做出板子用不了或者完全不匹配的要好一些。

伊丽莎白的学习之路 8998

kemeas算法继续优化——elkan kmeas算法

题记:又是凌晨3点的夜 elkan kmeans算法 在我的上一篇博客《kmeans算法性能改进_kmeans++算法+kmeans++优化算法+距离计算优化》中,在一般kmeans算法的基础上,添加了对于初始条件和距离计算更上的一些优化技巧。这篇博客聊一聊elkan算法,其实也是对于kmeans运行速度的优化算法。主要作用与kmeans的距离计算过程。 原理 假如我们已经知道任意两个样本之间的距离,再假设我们已经知道了样本1与聚类中心1之间的距离,根据三角性两边之和大于第三边,c+d>a,所以如果

铁血军的小博客 7065

【解决】在同一个select中count(*)取别名,作为查询的另一个元素的组成部分,出现异常。

直接看代码吧。 ① 第一种将count()取别名c,这种写法是错误的,因为下面的sum/c SQL不认识 ② 第二种 将count() 直接写入到查询的元素中的部分,这样直接SQL就查出来了 1、 select user_name, count(distinct(DATE_FORMAT(create_time,'%Y-%m-%d'))) as c sum(user_count) as userNum, sum(user_count)/.

CodingLJ 2567

通过Power Platform自定义D365 CE 业务需求 - 4. 使用Power Automate

Power Automate构建块Power Automate中的连接器流的类型和用途流中的动态值和表达式使用变量、循环和条件在Power Automate中处理审批业务场景、用例和实现Power Virtual Agent的概念Power Virtual Agent的构建块配置Power Virtual Agent示例在公共网站/门户中部署Power Virtual Agent业务场景、用例和实现。

Martin-Mei的博客 560

单表查询

一 单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键字的执...

aggressive2019 156

北斗导航 | 2023 PTTI会议论文 2023 ITM会议论文 2022 ION GNSS+ 会议论文下载:ION 美国导航学会

2023 国际技术会议(ITM) 2023 精密时间和时间间隔系统和应用会议(PTTI) 2022 美国导航学会国际会议(ION GNSS +)

尘世冰封的专栏 4613

YOLOv11 改进 - SPPF模块 | 发论文神器!LSKA注意力改进SPPF,增强多尺度特征提取能力,高效涨点!!!

本文介绍了Large Separable Kernel Attention (LSKA)模块及其在YOLOv11中的结合应用。LSKA旨在解决Visual Attention Networks (VAN)使用大内核卷积时的计算效率问题,通过将2D深度卷积层的卷积核分解为级联的水平和垂直1-D卷积核,降低了计算复杂度和内存占用,且使VAN更关注物体形状。我们将集成LSKA的SPPF_LSKA模块引入YOLOv11,大量实验表明,改进后的模型在对象识别、检测、分割和稳健性测试上表现出色。

魔改工程师的博客 1279

SAP SELECT数据表统计与求和

在一对多的inner join进行内表连接时,如果取出的数据有重复,前面加上distinct,这样可以删除重复的,也可以用 DELETE ADJACENT DUPLICATES FROM ”内表名“.

SAP ABAP开发技能记录分享 1253

使用Simulink对基于GaN器件的高频电源进行建模与仿真,重点在于优化其效率

本文介绍了基于Simulink的GaN器件高频电源仿真建模方法。通过7个步骤详细讲解系统构建过程:从创建模型、设置电源、配置GaN开关网络,到添加磁性元件、负载和控制器设计,最后进行仿真分析。重点探讨了效率优化策略,包括开关频率选择、磁性元件优化、散热设计改进及控制策略调整。该教程为GaN器件在电力电子系统中的应用提供了完整的仿真流程指导,有助于设计人员验证方案并优化性能。

amy_mhd的博客 234

select count(*)底层究竟干了啥么?

点击上方“Java后端技术”,选择“置顶或者星标”你关注的就是我关心的!作者:贾春生“SELECT COUNT( * ) FROM TABLE” 是个再常见不过的 SQL...

Java后端技术 435

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

你知道select count(*)底层究竟干了啥么?

作者:贾春生https://blog.didiyun.com/index.php/2019/01/08/mysql-count/“SELECT COUNT( * ) FR...

架构师小秘圈 1205

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

mysql count 底层原理_SELECT COUNT(*) 底层究竟干了啥么?

一、InnoDB 全表 COUNT(*)二、数据结构三、MyISAM 全表 COUNT(*)四、几个问题SELECT COUNT( * ) FROM TABLE” 是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表的存储引擎,在此前提下,COUNT( * )操作的时间复杂度为 O(N),其中 N 为表的行数。而 MyISAM 表中...

weixin_39700548的博客 385

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

select * 和select 1,select count(*)和select count(1)

1、select * 和select 1的区别 如果要返回数据,使用select * ,如果要判断有没有结果使用select 1; 2、select count(*)和select count(1)的区别 一般情况下,select count(*)和select count(1)两个返回的结果是一样的。

m0_63725962的博客 1万+

select count(*) 底层究竟做了什么?

阅读本文大概需要 6.6 分钟。 SELECT COUNT( * ) FROM t是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表的存储引擎,在此前提下,COUNT( * )操作的时间复杂度为O(N),其中 N 为表的行数。 而MyISAM表中可以快速取到表的行数。这些实践经验的背后是怎样的机制,以及为什么需要/可以是...

良月柒 6296

select count(*)底层究竟做了什么?

SELECT COUNT( * ) FROM t是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表的存储引擎,在此前提下,COUNT( * )操作的时间复杂度为O(N),其中 N 为表的行数。 而MyISAM表中可以快速取到表的行数。这些实践经验的背后是怎样的机制,以及为什么需要/可以是这样,就是此文想要探讨的。 先来看...

KHOST的博客 2591

select count(*) count(1) count(column)的区别

MySQL中COUNT(*)、COUNT(1)和COUNT(column)的区别: COUNT(*)统计所有行数,包括NULL值,不利用索引; COUNT(1)与COUNT(*)效果相同,仅写法不同; COUNT(column)只统计指定列的非NULL值,可利用索引优化性能。 使用建议:统计全表行数用COUNT(*),统计某列有效数据用COUNT(column)。

码出财富,敲出大千世界 1729

SELECT COUNT(*) 会造成全表扫描吗

SELECT COUNT(*) 会造成全表扫描吗

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 1087

select count(*) 底层到底干了啥?

作者:贾春生,http://dwz.win/mygSELECT COUNT( * ) FROM TABLE 是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中...

代码技巧 502

SELECT COUNT(*) 底层到底干了什么?(干货,认真读完你就了解透彻了!)

SELECT COUNT( * ) FROM TABLE 是个再常见不过的 SQL 需求了。 在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表的存储引擎,在此前提下,COUNT( * )操作的时间复杂度为 O(N),其中 N 为表的行数。 而 MyISAM 表中可以快速取到表的行数。这些实践经验的背后是怎样的机制,以及为什么需要/可以是这样,就是此文想要探讨的。 先来看一下概况,MySQL COUNT( * ) 在 2 种存储引擎中的部分问题: 一、InnoD

98渣渣辉的博客 1267

一文读懂 select count(*) 底层原理

作者:贾春生“SELECT COUNT( * ) FROM TABLE” 是个再常见不过的 SQL 需求了。在 MySQL 的使用规范中,我们一般使用事务引擎 InnoD...

公众号:Java后端 3147
上一篇: JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
下一篇: 艿艿周末又肝了一篇万字 Dubbo 文章,Spring Boot + Nacos + Sentinel + 参数校验,美滋滋~...
公众号-芋道源码
博客等级 码龄10年 1631粉丝 377原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值