当前位置: 首页 > ops >正文

【MySQL系列】SQL 分组统计与排序

csdn

博客目录

    • 引言
    • 一、基础语法解析
    • 二、GROUP BY 的底层原理
    • 三、ORDER BY 的排序机制
    • 四、NULL 值的处理策略
    • 五、性能优化建议
    • 六、高级变体查询

引言

在现代数据分析和数据库管理中,分组统计是最基础也是最核心的操作之一。无论是业务报表生成、用户行为分析还是系统性能监控,我们经常需要按照某个字段对数据进行分组,然后计算每组的记录数量或其他聚合值。

一、基础语法解析

让我们首先分析文章开头给出的基础 SQL 查询语句:

SELECTnode_execution_id,COUNT(*) AS count
FROMpublic.workflow_node_executions
GROUP BYnode_execution_id
ORDER BYcount DESC;

这个查询由几个关键部分组成:

  1. SELECT 子句:指定要查询的列和聚合函数。这里选择了 node_execution_id 列和 COUNT(*) 聚合函数,后者会计算每组的行数,并使用 AS 关键字将结果列命名为 count

  2. FROM 子句:指定数据来源的表,这里是 public.workflow_node_executionspublic 是模式名(schema),在多租户数据库环境中特别重要。

  3. GROUP BY 子句:定义分组的依据列。数据库引擎会根据 node_execution_id 的值将表中的记录分成若干组,每组拥有相同的 node_execution_id 值。

  4. ORDER BY 子句:指定结果的排序方式。DESC 表示降序排列,即 count 值大的组排在前面。
    在这里插入图片描述

二、GROUP BY 的底层原理

理解 GROUP BY 的执行原理对于编写高效的 SQL 查询至关重要。当执行包含 GROUP BY 的查询时,数据库引擎通常会按照以下步骤操作:

  1. 数据扫描:首先从表中读取所有满足条件的行(如果没有 WHERE 子句则读取全部数据)。

  2. 哈希分组:数据库会创建一个哈希表,以 GROUP BY 列的值作为键。对于每一行,计算 node_execution_id 的哈希值,并将该行放入对应的哈希桶中。

  3. 聚合计算:对于每个哈希桶(即每个分组),计算指定的聚合函数(如 COUNT(*)SUM()AVG() 等)。

  4. 结果生成:将每个分组的键值(node_execution_id)和聚合结果(count)组合成结果行。

值得注意的是,现代数据库优化器可能会根据表大小、索引情况等因素选择不同的分组算法,如排序分组法(sort-group)等,但哈希分组是最常见的实现方式。

三、ORDER BY 的排序机制

ORDER BY count DESC 决定了最终结果的呈现顺序。数据库引擎在完成分组和聚合后,会对结果集进行排序:

  1. 内存排序:如果结果集较小,数据库会在内存中使用快速排序等算法直接完成排序。

  2. 外存排序:对于大型结果集,数据库可能采用归并排序等外部排序算法,将中间结果暂存到磁盘。

  3. 索引利用:如果 count 列上有索引,某些数据库可能会利用索引来优化排序过程。

降序排列(DESC)会将较大的 count 值排在前面,这在分析高频事件或热门条目时特别有用。

四、NULL 值的处理策略

在分组操作中,NULL 值需要特别注意。SQL 标准规定:

  • 所有 NULL 值会被视为相同值归入同一组
  • 如果 node_execution_id 包含 NULL 值,这些记录会被聚合到一个特殊的分组中

如果业务上需要排除 NULL 值,应该显式添加过滤条件:

SELECTnode_execution_id,COUNT(*) AS count
FROMpublic.workflow_node_executions
WHEREnode_execution_id IS NOT NULL
GROUP BYnode_execution_id
ORDER BYcount DESC;

五、性能优化建议

对于大型数据表,分组统计操作可能相当耗费资源。以下是几个优化建议:

  1. 索引优化:在 node_execution_id 上创建索引可以显著加速分组操作。对于这个查询,复合索引 (node_execution_id) 就足够。

  2. 分区表:如果表数据量极大,考虑按 node_execution_id 的范围或哈希值进行分区,可以并行化分组操作。

  3. 物化视图:对于频繁执行的相同分组查询,可以创建物化视图预先存储结果。

  4. 限制结果集:如果只需要前 N 个结果,添加 LIMIT 子句避免处理全部数据:

SELECTnode_execution_id,COUNT(*) AS count
FROMpublic.workflow_node_executions
GROUP BYnode_execution_id
ORDER BYcount DESC
LIMIT 100;

六、高级变体查询

基于基础查询,我们可以扩展出更多有用的分析:

  1. 添加筛选条件:只统计特定时间范围内的执行情况
SELECTnode_execution_id,COUNT(*) AS count
FROMpublic.workflow_node_executions
WHEREexecution_time BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BYnode_execution_id
ORDER BYcount DESC;
  1. 多列分组:同时按节点 ID 和执行状态分组
SELECTnode_execution_id,status,COUNT(*) AS count
FROMpublic.workflow_node_executions
GROUP BYnode_execution_id, status
ORDER BYcount DESC;
  1. HAVING 子句:只返回满足特定条件的分组
SELECTnode_execution_id,COUNT(*) AS count
FROMpublic.workflow_node_executions
GROUP BYnode_execution_id
HAVINGCOUNT(*) > 100
ORDER BYcount DESC;

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

http://www.xdnf.cn/news/8712.html

相关文章:

  • Vue-数组操作方法技术解析大纲
  • 【爬虫学习】Python数据采集进阶:从请求优化到解析技术实战
  • 解决论文中字体未嵌入的问题
  • Q2:如果 Channel 没有关闭,读取会一直阻塞吗?
  • leetcode654.最大二叉树:递归分治下的最大值索引定位与树构建
  • 显示docker桌面,vnc远程连接docker
  • Android应用中设置非系统默认语言(使用Kotlin)
  • 机械师安装ubantu双系统:三、GPT分区安装Ubantu
  • 【医学影像 AI】医学影像 AI 入门:PyTorch 基础与数据加载
  • 并发编程艺术--AQS底层源码解析(一)
  • 计算机视觉---YOLOv2
  • [特殊字符] Function Calling 技术详解与 Qwen 模型实践指南
  • mqtt数据包举例
  • 博客摘录「 游戏开发笔记(九)——技能系统」2025年5月25日
  • SAP重塑云ERP应用套件
  • AI数据治理破局的战略重构
  • 【MPC控制】番外篇:MPC 与 机器学习/深度学习 —— 双雄会的相似与不同
  • 计算机网络学习(六)——UDP
  • 远程办公时代macOS访问解决方案:兼顾效率提升与安全防护的实用架构指南
  • 如何利用AI工具提升工作效率?
  • 2021年认证杯SPSSPRO杯数学建模B题(第二阶段)依巴谷星表中的毕星团求解全过程文档及程序
  • Mysql高版本(8.0及以后)Linux安装
  • 删除链表的倒数第N个结点--LeetCode
  • MySQL的存储引擎
  • 什么是 Spring MVC 的异步请求处理?
  • 如何在uniapp H5中实现路由守卫
  • JVM规范之栈帧
  • 15.1 【基础项目】使用 HTML、CSS 和 TypeScript 构建的简单计数器应用
  • LLM之Agent:Mem0的简介、安装和使用方法、案例应用之详细攻略
  • C# Windows Forms应用程序-002