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

SQL优化案例:巧用主键分页减少DISTINCT开销

SQL优化案例:巧用主键分页减少DISTINCT开销

SELECT task.task_name AS taskName, GROUP_CONCAT( DISTINCT template.template_name SEPARATOR ';' ) AS templateName, a.batch_number AS batchNumber, COUNT( DISTINCT a.task_detail_id ) AS detailNum, MIN( a.STATUS ) AS STATUS, SUM( CASE WHEN a.STATUS = '2' THEN 1 ELSE 0 END ) AS docNum, SUM( CASE WHEN a.STATUS = '2' THEN 1 ELSE 0 END ) AS successNum, SUM( CASE WHEN a.STATUS = '1' THEN 1 ELSE 0 END ) AS failNum, a.generation_method AS generationMethod, MIN( a.create_time ) AS createTime, a.last_update_time AS lastUpdateTime FROM table_batch a INNER JOIN table_template template ON a.acc_template_id = template.acceptance_template_id INNER JOIN table_task task ON task.task_id = template.task_id WHERE task.task_id = '123456' GROUP BY a.batch_number ORDER BY createTime DESC LIMIT 20 # limit是分页器添加的

背景

线上一张分表数据量达900w+,某查询在小数据量时<1s,数据量上来后飙到1min+。

适用场景

  • 页面数据量有上限(可预期,比如500,1000)
  • GROUP BY 分组后总量远大于单页数据量
  • 无法改造索引或表结构

核心优化点

优化前优化后
全表GROUP BY + DISTINCT → LIMIT先分页取主键batch_number → 再IN查询
900w+数据参与去重仅500条数据参与去重

效果

查询时间从 60s+ 降至 20s 左右,优化约66%

问题分析

SIMPLEtaskPRIMARY,index_task_idPRIMARY202const1Using temporary; Using filesort
SIMPLEtemplatePRIMARY,idx_template_id,idx_task_id,idx_acceptance_template_ididx_task_id403const2
SIMPLEaidx_batch_task,idx_acc_template_ididx_acc_template_id203acceptancedoc.template.acceptance_template_id1118Using index condition

explain 显示索引全命中,但 COUNT(DISTINCT) 和 GROUP_CONCAT(DISTINCT) 导致索引扫描后还需额外去重,成为性能瓶颈。
在小数据量时,查询1s内,数据量达到900w+时,查询时间来到1min+

排查后,发现,count(distinct)以及group_concat(distinct)严重拖慢了查询效率
或者说主要是distinct,原先只需扫描索引,现在多了一步去重。

优化思路

受业务限制,分页最大500条,但分组后总量8000+。参考游标分页思想——缩小WHERE范围。
由于无法使用 > 游标,改用两步法:

  • 查询所需页的主键id
SELECT a.batch_number AS batchNumber FROM table_batch a INNER JOIN table_template template ON a.acc_template_id = template.acceptance_template_id INNER JOIN table_task task ON task.task_id = template.task_id WHERE task.task_id = '123456' GROUP BY a.batch_number ORDER BY MIN( a.create_time ) DESC limit 20
  • 按主键id查询所需页的所有数据
SELECT task.task_name AS taskName, GROUP_CONCAT( DISTINCT template.template_name SEPARATOR ';' ) AS templateName, a.batch_number AS batchNumber, COUNT( DISTINCT a.task_detail_id ) AS detailNum, MIN( a.STATUS ) AS STATUS, SUM( CASE WHEN a.STATUS = '2' THEN 1 ELSE 0 END ) AS docNum, SUM( CASE WHEN a.STATUS = '2' THEN 1 ELSE 0 END ) AS successNum, SUM( CASE WHEN a.STATUS = '1' THEN 1 ELSE 0 END ) AS failNum, a.generation_method AS generationMethod, MIN( a.create_time ) AS createTime, a.last_update_time AS lastUpdateTime FROM table_batch a INNER JOIN table_template template ON a.acc_template_id = template.acceptance_template_id INNER JOIN table_task task ON task.task_id = template.task_id WHERE task.task_id = '123456' and batch_number in #{pageBatchNumber} GROUP BY a.batch_number ORDER BY createTime DESC

拆成两个sql,减少了去重的数据量,由原先对所有去重再分页,变成了先分页再去重
尽管先分页获取主键id,受限于大数据量下group by的速率,但相较之前,查询速度还是优化了7成左右

http://www.cnnetsun.cn/news/4115825.html

相关文章:

  • 制造业数据防篡改:从神钢事件看供应链诚信体系建设
  • 电视盒子刷机成Linux服务器的完整实战:amlogic-s9xxx-armbian从零到一
  • 库存管理P系统订货上限计算:从原理到Excel/Python实践
  • 摄像头流媒体太乱?go2rtc 用一个文件解决多协议统一出流
  • paper.json:构建机器可读学术论文,赋能LLM智能体高效科研
  • 从零搭建本地AI服务器:低成本部署大模型与Stable Diffusion实战指南
  • ERP采购订单变更失控:从根源分析到SAP系统实现完整控制方案
  • 全电动飞机试飞技术解析:从5美元电费看能量管理与工程挑战
  • AKConv:自适应卷积核改进目标检测性能的原理与实践
  • 别再被网盘限速折磨!开源网盘直链提取工具从零上手指南
  • Go语言数据结构、算法与设计模式一站式学习指南
  • PhoneHarness:构建混合GUI、CLI与工具的手机智能体统一执行框架
  • N沟道与P沟道MOSFET核心差异详解:从原理到选型避坑指南
  • RDP Wrapper完整实操指南:普通Windows电脑也能多人同时远程登录
  • AI珠宝精修到底是什么?和网上说的AI修图是一回事吗?
  • K7d秒级分叉K8s集群:加速AI训练与GRPO实验的工程实践
  • Qwen3.8-27B本地部署实战:消费级硬件跑通大模型,实测对比云端API
  • 高效能应用
  • 号称厘米级的蓝牙AOA定位,到医院项目就翻车?行业人该清醒了
  • Rhino.Inside.Revit 上手指南:30 分钟让 Rhino 与 Revit 实时联动,告别反复导模型
  • [校大]27届二本巢湖学院JAVA简历:小公司简历通过率仅3%
  • 超简易实时HTML编辑器
  • 手机号查QQ号如何实现?开源 Python 工具 phone2qq 极速速查指南
  • Bun 后端开发中如何实现无反射依赖注入:dunx 库实战指南
  • 抖音批量下载工具douyin-downloader终极指南:30分钟从零到千条视频入库
  • OBS多平台同时推流保姆级教程:obs-multi-rtmp一键搞定多平台直播
  • Linux网络命名空间实战:从零构建虚拟网络拓扑
  • 个人无营业执照如何在抖音、视频号卖课?2026 知识博主合规变现防坑全指南
  • 从信息收集到权限提升:攻克困难靶机的系统化渗透测试实战
  • Figma 汉化不求人:4383 条人工校验词条,把英文界面换成中文只差一步