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

distinct导致sql超时

前言

昨天敲着敲着代码,小杨哥跑过来给我说,快看他们大会议室演示报错了,还是一堆错了。完了啊在演示的时候报错!!!接下来我们分析一下是什么原因吧。

问题分析

查看日志: 从日志打印看明显的是sql报错了
在这里插入图片描述

这个sql明显是分页查询插件在统计分页条数,日志第一行有个distinct关键字,distinct我是从来没有用到过分页中过,这个distinct会根据后面的所有字段去重,性能太差导致连接超时。

小杨哥在这时说,人大金仓distinct只会对第一个字段去重处理,其他字段随机取一条。我当时就否定了他这个观点,有点经验的人也不会这么设计distinct吧,你这不是违反sql规范吗。实际上小杨哥说的那个语法应该是这个DISTINCT ON (column1, column2, ...) column1, column2, ...

我也马上把我结论告知了相关同事,经过测试确实也是因为这个distinct导致请求时长超时。

解决方案

问题已经定位到了,就是distinct后面的字段太多了。用distinct主要目的就是解决 在1对多的连表查询时候,根据主表数据去重。

  • 方式1:使用 distinct on ('id') 指定重复列
  • 方式2:使用group by取代distinct

总结

  1. 在 SQL 中,DISTINCTGROUP BY 都用于处理重复数据,但它们的执行原理和性能特征有所不同。在大多数情况下,GROUP BY 在处理聚合时可能比 DISTINCT 更高效,但实际性能依赖于具体查询和数据集的特性。

    在查询1对多的数据情况,只需要返回主表的数据,这时候distinctdistinct ongroup by 都满足查询结果
    eg: select distinct on (a.id) a.* from atable a left join btable b on a.id= b.a_id where b.name = 'xx'
    这种情况我们可以使用 distinct on (id) ,其他情况 或者是需要调用聚合函数时候就用 group by

  2. 在分页列表查询优化中,我还可以考虑去单独优化count sql
    开发中大多时候我们写分页查询,都是不需要管统计条数这个sql的,因为插件自动帮我们拼装执行了。有些时候需要优化的话,我们可以考虑覆盖统计sql,不动service代码。一般的分页插件在mapper中定义一个命名规则为 queryname +_COUNTmapper就行了,分页插件在执行queryname 查询的的时候,就会优化查询是否有queryname_COOUNT的统计条数SQL,有就使用自定义的。

    自定义的统计sql可以减少查询字段、在不影响统计结果的情况减少连表查询,来提升统计的效率

ps:有服务器需求的联系我返dian,提供技术支持哦

扩展知识 (distinct 和 group by 区别)

  • DISTINCTDISTINCT 用于从查询结果中去除重复的行,返回唯一的值。distinct on ('colunm ..') 指定需要去重的列,可以返回不参与去重的列,没有参与去重的列随机返回一条数据。

  • GROUP BYGROUP BY 用于将结果集按一个或多个列进行分组,并通常与聚合函数(如 COUNTSUM 等)一起使用。不能查询没有参与分组的字段。

性能测试

查询相同的sql 使用日志中的sql作为测试,使用distinctdistinct ongroup by 测试一下执行时间 。用时最短的是 distinct on ,因为只根据一个id进行去重;第二是group by ,毕竟分组的字段太多了差不多30个;distinct (去重30个字段)时间就直接指数级的增长了,列表查询的时候禁用啊。

  • distinct:14.2s (distinct后只跟一个字段的话就是 0.2s)
    在这里插入图片描述

  • distinct on (id): 0.7s
    在这里插入图片描述

  • group by: 1.9s (如果只查一个id的话就0.2s)

    在这里插入图片描述


http://www.kler.cn/news/327254.html

相关文章:

  • NAT模式 LVS负载均衡群集部署
  • 【LeetCode】每日一题 2024_9_30 座位预约管理系统(堆)
  • JWT 漏洞 - 学习手册
  • 【BUG等级划分 S,A-C】
  • 技术成神之路:设计模式(十九)桥接模式
  • ffmpeg录制视频功能
  • 无人机在科研与教育领域的应用!
  • 计算机网络实验4——实现局域网的组建、互连及VLAN的划分
  • PHP中常用的字符串函数详解
  • springboot厨房达人美食分享平台(源码+文档+调试+答疑)
  • HTML+CSS - 表单交互(一)
  • 堆【数据结构C语言版】【 详解】
  • 【Transformers实战篇1】基于Transformers的NLP解决方案
  • 公网IP和内网IP比较
  • 数据结构之手搓顺序表(顺序表的增删查改)
  • plt等高线图的绘制
  • 智能家居技术的前景和现状
  • LeetCode讲解篇之15. 三数之和
  • Frp服务部署
  • 【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
  • string为什么存储在堆里
  • EP42 公告详情页
  • Mac制作Linux操作系统启动盘
  • 蜘蛛爬虫的ip来自机房,用户的爬虫来自于哪里
  • 日常工作第10天:
  • web笔记
  • uni-app ios 初次进入网络没有加载 导致出现异常
  • 计算机毕业设计 基于深度学习的短视频内容理解与推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
  • nacos client 本地缓存问题
  • 信息安全数学基础(23)一般二次同余式