雷区场景:仍然是某2G+2C的项目用户管理模块,比较普通的增删改查功能。近日被吐嘈打开人员列表(用户数据量在70-80万之间)展示页面超慢!有时还会请求超时。。。

初步排查:NetWork找到了响应慢为获取人员列表数据的接口,响应时间竟然超过了10s,看来实施的同学心态普遍都是极好了!!!然后安排了开发兄弟直接排查日志及查询脚本,确实也查到了一些关键问题,比如下面的查询脚本:

实际执行的脚本为:

select * from          
(SELECT bu.*, cp.name AS companyName, cp.id AS companyId 
FROM xxx_user bu 
LEFT JOIN xc_company_user cu ON cu.user_id = bu.user_id 
LEFT JOIN xc_company cp ON cp.id = cu.company_id 
LEFT JOIN xxx_dept bd ON bd.id = bu.dept_id 
WHERE bu.is_deleted = 0) t 
limit 0, 100;

而系统中集成了MybatisPlus框架,采用了自带的分页查询模式。所以在xml脚本中没有写入limit脚本,运行过程中mp会在脚本末尾自动附加上limit脚本。开发人员认为是该sql语句写的有问题,没有必要在外层又套了一个select t.* from的壳,认为内部的select做的是全表查询,所以修改了查询脚本为:

SELECT bu.*, cp.name AS companyName, cp.id AS companyId 
FROM xxx_user bu 
LEFT JOIN xc_company_user cu ON cu.user_id = bu.user_id 
LEFT JOIN xc_company cp ON cp.id = cu.company_id 
LEFT JOIN xxx_dept bd ON bd.id = bu.dept_id 
WHERE bu.is_deleted = 0
limit 0, 100;

实则不然,两者的执行效率相差无几

当然,从脚本功能上来讲确实是没有必要在外层重新包装select t.* from的壳,还是做了这一步优化。

那么,问题来了,单独执行脚本基本都在100ms以内,而接口总体响应时间却在10s钟左右。那问题很有可能出在业务逻辑上了,接口程序查询完sql之后又做了其它的业务逻辑处理了?我得到的答复是:没有!!!

不放心的我找到程序位置又确认了一遍,确实没有:

这就有点意思了,按照惯例还是需要跟进mp的baseMapper底层实现去分析原因了。起初也曾怀疑过是mp查询结果反序列化耗时引起的,但并没有查到相关的配置参数,而且测试了单页查询10条和500条数据响应时间差不多就打消了这个疑虑,还是查源码吧!

问题分析:一路漫长的调试源码(N多层嵌套),最终找到了mp的分页拦截器定义类PaginationInterceptor的intercept方法,

而sqlInfo.getSql()自动组装的查询总数据量的sql脚本竟然是:

SELECT COUNT(1) 
FROM xxx_user bu 
LEFT JOIN xc_company_user cu ON cu.user_id = bu.user_id 
LEFT JOIN xc_company cp ON cp.id = cu.company_id 
LEFT JOIN xxx_dept bd ON bd.id = bu.dept_id 
WHERE bu.is_deleted = 0;

执行了一遍竟然耗时7s钟!!!总算找到问题所在了,那么为何做一个count计算会这么慢呢,原因在于下面的几个left join,对于这种count而言,做这些left join纯粹是浪费时间啊!无语,mp的分页查询只是机械化的将原始sql脚本的select做了替换:

去掉这些无用的left join表之后,查询单表count耗时500ms。

解决方案: 目前只是确定了left join对count的性能损耗冗余量较大,针对该响应慢的接口做了如下优化,不使用mp自带的分页查询,单独写分页及count查询,而且优化查询方式,不再对每一页查询都做数据总量的查询,而是只在第一页和最后一页时重新查一遍总量,以节省系统开销。

优化后的接口响应时间第一页在600ms左右,第二页在100-200ms之间。

这只是目前临时的优化方案,对mp机械化的分页方式还是需要区分业务场景。

排雷日记 -- mybatisplus分页查询效率相关推荐

  1. MyBatis-Plus分页查询where后面的参数拼接错误报### The error occurred while setting parameters

    MyBatis-Plus分页查询条件参数拼接错误! ### The error may exist in file [D:\SourcrGit\IOT_sxx\iot-parent\iot\targe ...

  2. mybatis-plus分页查询三种方法

    mybatis-plus分页查询 一.前期准备表 1.配置类 二.使用selectPage 1.Service 2.结果 三.使用2种分页查询的写法 1.xml 2.Mapper 3.第一种写法 4. ...

  3. Mybatis-plus分页查询不生效之问题排查

    Mybatis-plus分页查询不生效之问题排查 一.问题描述 二.分析步骤 三.解决方案 四.总结 一.问题描述 在查询的时候,发现点击后台的分页器数字,第2页时候,数据还是和第1页的一致.就看后台 ...

  4. Mybatis-plus分页查询records为空,total不为空的问题

    Mybatis-plus分页查询records为空,total不为空的问题 问题图片 其实原来是分页配置文件的问题(3.4版本以后配置文件有所变化) @Beanpublic MybatisPlusIn ...

  5. mybatis-plus分页查询详解

    文章目录 一.官方文档 二.内置的分页方法 1.内置方法 2.selectPage单元测试 3.PaginationInnerInterceptor分页插件配置 三.分页原理分析 四.自定义分页方法 ...

  6. 使用 MyBatis-Plus 分页查询

    文章目录 一.MyBatis-Plus 二.使用步骤 1.引入库 2.在application.yml配置 3.启动类上面添加@MapperScan注解 4.实体类User 5.Mapper接口Use ...

  7. mybatis-plus分页查询_SpringBoot + MyBatisPlus 快速入门

    Hello,大家好!前面与大家分享了一次如何搭建Java项目脚手架,并且送给大家一个基础项目模板.那今天与大家分享如何使用这个基础项目,也就是快速上手 SpringBoots ➕ MyBatisPlu ...

  8. 多年以前提高asp.net分页查询效率的一个实例

    2004年数据库查询优化实例 情况:sqlserver 2000,资源表,记录近30万条.资源有一个整数的id字段,自动增量,但是资源可以被删除.所以,id并不连续. 用.net SqlDataAda ...

  9. node js+sql 后端分页查询效率越来越低解决方案

    创建分页的时候查询效率越来低的解决原因 1,没创建索引 CREATE INDEX index_name ON table_name(column_name,column_name) include(s ...

  10. Mybatis-Plus分页查询total始终为0

    一.问题 SpringBoot + Mybatis-Plus,使用分页查询,records有记录,total却始终为0. 二.原因 查看很多博客,说是因为没有加分页拦截器.加上了,total仍然为0, ...

最新文章

  1. Windows Server入门系列38 访问网络共享
  2. Hystrix 熔断器01—— 概述 || Hystrix 重要概念
  3. 关系数据库的设计理论
  4. MySQL的答理证和技艺撑持费用
  5. Delphi 一些函数解释
  6. Linux 文件 IO
  7. Java正则表达式, 提取双引号中间的部分
  8. ubuntu proxy
  9. mysql传参为数组,将数组传递给MySQL存储例程
  10. iOS阶段学习第31天笔记(UINavigationBar介绍)
  11. 移动硬盘插入电脑后不显示盘符
  12. CSDN:2020 年度 CSDN 博客之星评选——28 号【沉默王二】,感谢你投上的宝贵一票,感谢!
  13. 快速应对面试--分门别类--6.链表
  14. 什么叫域名解析SSL证书?
  15. python修改桌面壁纸_python设置windows桌面壁纸
  16. 浏览器刷新、关闭页面与统计在线人数
  17. 用Python爬取猫眼数据分析《无名之辈》
  18. 【解题报告】2017-2018 8th BSUIR Open Programming Contest-C Good subset 线性基+线段树
  19. python decimal_实例详解Python模块decimal
  20. 基于ssm医药药品管理系统

热门文章

  1. 修改文件错误:E45: 'readonly' option is set (add ! to override)
  2. oracle if else怎么用,oracle if else语句使用介绍
  3. MikroTik路由器配置
  4. Python高级用法:索引和切片
  5. python高级索引
  6. 【Verilog零基础入门-边看边练】学习笔记——第七讲 时序逻辑代码设计和仿真(三角波发生器)(一)
  7. 关于使用腾讯云播放器的遇到的坑
  8. 熔断器 java_SpringCloud之熔断器Hystrix的实现
  9. 湖南出台不动产登记新规 “小产权房”不予办理
  10. 17-[案例1]奇虎导航案例