mysql group by 执行原理及千万级别count 查询优化

大家好,我是蓝胖子,前段时间mysql经常碰到慢查询报警,我们线上的慢sql阈值是1s,出现报警的表数据有 7000多万,经常出现报警的是一个group by的count查询,于是便开始着手优化这块,遂有此篇,记录下自己优化过程中的心得。

优化慢sql前,肯定是要懂sql的查询逻辑,所以我先介绍下group by 语句的执行逻辑。

group by 执行逻辑

环境准备

拿下面这张表举例,这是一张记录文件夹id和用户id关联关系的表。其中dir_id代表文件夹id,uid代表用户id,还有个唯一索引是uniq_dir_id。

create table t_dir_user
(
id bigint unsigned auto_increment
primary key,
dir_id bigint default 0 not null,
uid bigint default 0 not null,
constraint uniq_dir_id
unique (dir_id, uid)
)

表一共有7000多万的数据。下面开始介绍使用group by 语句时sql执行的原理。

没有用到索引的情况

先说下结论,group by后面的列如果不能使用上索引,那么则会产生临时表且很可能产生文件排序的情况。

group by 语句有分 使用到索引和没有使用到索引的情况,先看看没有使用到索引的情况。假如我想查询在一些文件夹范围内,用户关注的文件夹数量。那我可以写出下面这样的sql。

explain select count(1), uid  
from t_dir_user  
where dir_id in (1803620,4368250,2890924,2033475,3038030)  
group by uid;

使用explain分析时,会发现这个查询是使用到索引的,且Extra 那一栏会出现下面的信息。

Using index condition; Using temporary; Using filesort

上述信息代表了查询是使用到了索引来做where条件查询,并且使用到了临时表和文件排序。

注意📢📢 ❗️ 临时表和文件排序这两个操作都是性能不佳的操作,写sql时应尽量避免。

现在来对这种情况做更加具体的分析,在上述例子中,mysql相当于建立了一张临时表,具体是内存的临时表还是磁盘的临时表要看临时表数据量大小,内存放不下会放到磁盘上。

临时表一列存放需要分组的值,上述案例中就是 uid,一列存放统计出来的count值,mysql会一遍扫描uniq_dir_id索引,一边向这个临时表中写入数据或更新count值,当索引扫描完成后,再将填满数据的临时表做下排序然后返回给客户端。注意这个排序的行为,如果需要排序的数据量很大则会产生文件排序,否则则是内存排序。

使用到索引的情况

再来看看group by 后跟的列能使用到索引的情况。

先说下结论,使用到索引的时候,mysql会使用内置的聚合函数来进行操作,而不是创建临时表。并且节省了排序这一步,这种方式会更高效。

还是拿上面t_dir_user 这张表举例,这次我们要查一定文件夹范围内,一个文件夹与多少个用户关联。我们可以这样写sql,

explain select count(1), dir_id  
from t_dir_user  
where dir_id in (1803620,4368250,2890924,2033475,3038030)  
group by dir_id;

此时explain分析后你会发现,虽然使用的是相同的索引,但是Extra这一栏的信息已经变了,Extra信息如下,

Using index condition; Using aggregate; Using index

Using aggregate 这条sql会使用mysql内置的聚合函数进行分组聚合的操作。

我们来具体分析下,因为group by此次是按dir_id文件夹id进行分组的,而dir_id刚好可以用上dir_id和uid建立的联合索引uniq_dir_id,并且索引是有序的,这样mysql在扫描索引的时候,就是一个文件夹id的索引数据扫描完成后,再次去扫描下一个文件夹id的索引数据,扫描的同时会对该文件夹id的count值进行累加。 这样一个文件夹的索引数据扫描完成后刚好就能知道这个文件夹id关联的uid的count值,并将这个值发送给客户端。

所以,整个过程其实是一边扫描索引对特定文件夹id的count值进行累加,一边将累加后的结果返回给客户端的过程。

注意📢📢,mysql返回给客户端的结果并不是全部查询出来后才返回给客户端,而是可以边查边返回的。

整个过程是没有用上临时表的。这样的查询会更加高效。

使用索引的情况下如何优化千万级count group by查询

在了解完group by语句的执行逻辑后,我对线上的sql进行了分析,发现线上的sql的group by列是属于已经使用了索引的情况。那为啥还会慢呢?

Pasted image 20231114181147.png

因为即使是使用了索引,group by的过程还是会有扫描索引和进行累加的过程,由于扫描的数据量太大了,最终导致了sql整体耗时还是很慢,超过了1s的阈值。

既然如此,那就换一种优化思路,这也是对大数据量的聚合统计的一种常用手段。 业务大部分时候都是读多写少的,可以建立一张新表专门用于记录对应的文件夹管理的用户数,每次关联关系发生变化时,同时再更新下这张统计表的数量即可。而业务在查询数量时,则直接查统计表中的数据。 这种优化非常适合大数据量的统计。

除此以外,甚至还可以使用elasticsearch 这类型数据库存数据,在这个案例里,相当于就把t_dir_user整张表的数据同步到elasticsearch中,并且做mysql到elasticsearch集群数据的实时同步机制,这样以后在查询对应文件夹的关联人数时,可以直接在elasticsearch进行查询。elasticsearch会对每个字段建立倒排索引。由于倒排索引中会存储该索引的记录条数,在这个案例中就是dir_id对应的记录条数,所以在用elasticsearch进行dir_id的分组count查询时是相当快的。

我们线上已经有elasticsearch同步部分mysql表的机制了,基于此,我选择了方案2,直接在之前同步表中新增了t_dir_user这张表,并且修改了业务查询文件夹下关联人数的逻辑,改由直接查询elasticsearch。

其实,你可以发现由于elasticsearch的倒排索引内直接记录了数量信息,这个和由mysql建立新的统计表记录数量,原理其实是一致的,就是将高频的读count查询改由低频的更新操作。

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

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

相关文章

torch - FloatTensor标签(boolean)数值转换(1/0)

当我们数据集的标签为True/False的boolean型时,我们可以直接使用FloatTensor传入该标签。返回的数据为tensor([0.])或者tensor([1.]),这十分有利于二分类任务的预测标签对错判断。 这个用法是基于Python的布尔类型与整数之间的隐式类型转换。在Python中&…

PostgreSQL 数据类型

文章目录 PostgreSQL数据类型说明PostgreSQL数据类型使用单引号和双引号数据类型转换布尔类型数值类型整型浮点型序列数值的常见操作 字符串类型日期类型枚举类型IP类型JSON&JSONB类型复合类型数组类型 PostgreSQL数据类型说明 PGSQL支持的类型特别丰富,大多数…

编译和链接

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理(预编译) 2.2 编译 2.2.1 词法分析: 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2…

MXNet中图解稀疏矩阵(Sparse Matrix)的压缩与还原

1、概述 对于稀疏矩阵的解释,就是当矩阵里面零元素远远多于非零元素,且非零元素没有规律,这样的矩阵就叫做稀疏矩阵,反过来就是稠密矩阵,其中非零元素的数量与所有元素的比值叫做稠密度,一般稠密度小于0.0…

搭建知识付费系统的最佳实践是什么

在数字化时代,搭建一个高效且用户友好的知识付费系统是许多创业者和内容创作者追求的目标。本文将介绍一些搭建知识付费系统的最佳实践,同时提供一些基本的技术代码示例,以帮助你快速入门。 1. 选择合适的技术栈: 搭建知识付费…

Vim + YCM + clangd

目录 1. Vim的安装 1.1 Vim安装vim-plug2. 安装YCM3. 进行语言补全配置 3.1 测试效果 1. 目的:让 Vim 像 C/C IDE 一样具备自动补全代码等功能 2. YCM:YouCompleteMe GitHub - ycm-core/YouCompleteMe: A code-completion engine for Vi…

C#asp.net考试系统+sqlserver

C#asp.net简易考试系统 sqlserver在线考试系统学生登陆 判断学生是否存在 选择课程名 科目 可以进行答题操作,已经考试的课程不能再次答题, 自动根据课程名对应的题库生成试卷界面 加入选项类容 说明文档 运行前附加数据库.mdf(或sql生成数…

【机器学习】线性回归算法:原理、公式推导、损失函数、似然函数、梯度下降

1. 概念简述 线性回归是通过一个或多个自变量与因变量之间进行建模的回归分析,其特点为一个或多个称为回归系数的模型参数的线性组合。如下图所示,样本点为历史数据,回归曲线要能最贴切的模拟样本点的趋势,将误差降到最小。 2. 线…

Android并发编程与多线程

一、Android线程基础 1.线程和进程 一个进程最少一个线程,进程可以包含多个线程进程在执行过程中拥有独立的内存空间,而线程运行在进程内 2.线程的创建方式 new Thread: 缺点:缺乏统一管理,可能无限制创建线程&…

卷积神经网络(CNN)mnist手写数字分类识别的实现

文章目录 前期工作1. 设置GPU(如果使用的是CPU可以忽略这步)我的环境: 2. 导入数据3.归一化4.可视化5.调整图片格式 二、构建CNN网络模型三、编译模型四、训练模型五、预测六、知识点详解1. MNIST手写数字数据集介绍2. 神经网络程序说明3. 网…

servlet页面以及控制台输出中文乱码

如图: servlet首页面: servlet映射页面: 以及控制台输出打印信息: 以上页面均出现中文乱码 下面依次解决: 1、首页面中文乱码 检查你的html或者jsp页面中meta字符集 如图设置成utf-8 然后重启一下tomcat 2、servl…

企业数字化过程中数据仓库与商业智能的目标

当前环境下,各领域企业通过数字化相关的一切技术,以数据为基础、以用户为核心,创建一种新的,或对现有商业模式进行重塑就是数字化转型。这种数字化转型给企业带来的效果就像是一次重构,会对企业的业务流程、思维文化、…

【数据结构与算法】JavaScript实现树结构(一)

文章目录 一、树结构简介1.1.简单了解树结构1.2.树结构的表示方式 二、二叉树2.1.二叉树简介2.2.特殊的二叉树2.3.二叉树的数据存储 三、二叉搜索树3.1.认识二叉搜索树3.2.二叉搜索树应用举例 一、树结构简介 1.1.简单了解树结构 什么是树? 真实的树:…

VS2017 IDE 编译时的 X86、x64位 是干什么的

指定编译出的程序是x86架构下的32位程序还是64位程序 VS2017项目配置X86改配置x64位_winform:把项目由x86改为x64-CSDN博客 vs平台选项:Any CPU,x86,x64_vs anycpu-CSDN博客

Jenkins中强制停止停不下来的job

# Script console 执行脚本 Jenkins 的提供了 script console 的功能,允许你写一些脚本,来调度 Jenkins 执行一些任务。 我们就可以利用 script console 来强制停止 job 执行。 首先进入 Jenkins 的 script console 页面: script console 路…

如何利用TSINGSEE青犀智能分析网关算法从人员、设备、行为三大角度进行监狱智能化升级改造

监狱作为关押犯人的重要场所,十分需要全天候全方位无死角的监控,但由于狱警人力有限,无法达到目前的监控需求。并且在监狱中,犯人众多也极易发生口角冲突,如若没有及时处理,就会发生难以挽回的意外。如何更…

MySQL分页查询的工作原理

前言 MySQL 的分页查询在我们的开发过程中还是很常见的,比如一些后台管理系统,我们一般会有查询订单列表页、商品列表页等。 示例: SELECT * FROM goods order by create_time limit 0,10; 在了解order by和limit的工作原理之前&#xff0c…

Python | 机器学习之逻辑回归

​🌈个人主页:Sarapines Programmer🔥 系列专栏:《人工智能奇遇记》🔖少年有梦不应止于心动,更要付诸行动。 目录结构 1. 机器学习之逻辑回归概念 1.1 机器学习 1.2 逻辑回归 2. 逻辑回归 2.1 实验目的…

开发一款小程序游戏需要多少钱?

小程序游戏的开发成本因多种因素而异,无法提供具体的固定数字。以下是影响小程序游戏开发成本的一些关键因素: 游戏规模和复杂度: 小程序游戏可以是简单的休闲游戏,也可以是更复杂的策略游戏。规模和复杂度会影响开发所需的时间和…

字节跳动小程序开发:探索创新的数字化世界

在数字化时代,字节跳动小程序开发成为企业数字化转型的关键一环。通过这一平台,企业能够借助先进的技术和丰富的功能,实现创新、引领市场潮流。本文将通过一些简单的技术代码示例,带你深入了解字节跳动小程序开发的魅力。 1. 小…