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

我是如何把一个接口的响应时间从 2s 优化到 50ms 的

背景上周线上监控报警有一个用户列表查询接口的平均响应时间达到了 2.3 秒高峰期甚至超过 5 秒严重影响了用户体验。这个接口是我一年前写的当时数据量小没觉得有什么问题。现在用户表已经有 500 多万条数据了性能问题就暴露出来了。今天我把整个优化过程记录下来从问题定位到最终优化完成一步步带大家看如何把一个慢接口优化到 50ms 以内。第一步定位问题首先用 Postman 测试了一下接口确实很慢。然后我打开了 MySQL 的慢查询日志找到了对应的 SQL 语句sqlSELECT u.id, u.username, u.email, u.phone, r.role_name, d.dept_name FROM user u LEFT JOIN role r ON u.role_id r.id LEFT JOIN dept d ON u.dept_id d.id WHERE u.status 1 ORDER BY u.create_time DESC LIMIT 10 OFFSET 100000;执行时间2.1 秒。问题 1深度分页导致的性能问题LIMIT 10 OFFSET 100000这种写法会让 MySQL 扫描 100010 行数据然后丢弃前 100000 行只返回最后 10 行。当偏移量很大时性能会急剧下降。优化方案使用游标分页sql-- 优化前 SELECT * FROM user WHERE status 1 ORDER BY id DESC LIMIT 10 OFFSET 100000; -- 优化后 SELECT * FROM user WHERE status 1 AND id 100000 ORDER BY id DESC LIMIT 10;这样 MySQL 只需要扫描 10 行数据执行时间从 2.1 秒降到了 0.01 秒。问题 2没有合适的索引查看了一下表结构发现status、create_time和关联字段role_id、dept_id都没有建索引。优化方案添加合适的索引sql-- 给查询条件和排序字段建联合索引 CREATE INDEX idx_user_status_create_time ON user(status, create_time DESC); -- 给关联字段建索引 CREATE INDEX idx_user_role_id ON user(role_id); CREATE INDEX idx_user_dept_id ON user(dept_id);添加索引后查询时间降到了 0.3 秒。问题 3不必要的关联查询查看代码发现这个接口返回的角色名称和部门名称其实很少变化而且大部分用户都属于同一个部门和角色。优化方案使用缓存java运行// 原来的代码 ListUserVO userList userMapper.selectUserList(query); for (UserVO user : userList) { Role role roleMapper.selectById(user.getRoleId()); user.setRoleName(role.getName()); Dept dept deptMapper.selectById(user.getDeptId()); user.setDeptName(dept.getName()); } // 优化后的代码 // 先把所有角色和部门加载到缓存中 MapLong, String roleMap roleMapper.selectAll().stream() .collect(Collectors.toMap(Role::getId, Role::getName)); MapLong, String deptMap deptMapper.selectAll().stream() .collect(Collectors.toMap(Dept::getId, Dept::getName)); // 然后在循环中直接从缓存中获取 for (UserVO user : userList) { user.setRoleName(roleMap.get(user.getRoleId())); user.setDeptName(deptMap.get(user.getDeptId())); }这样就把原来的 N1 次查询变成了 3 次查询接口响应时间降到了 0.1 秒。问题 4返回了不必要的字段查看接口返回结果发现返回了很多不需要的字段比如password、salt、update_time等。优化方案只返回需要的字段java运行// 原来的代码 ListUser userList userMapper.selectList(queryWrapper); // 优化后的代码 ListUserVO userList userMapper.selectUserList(query);在 Mapper 中只查询需要的字段减少数据传输量。最终优化结果经过以上几步优化接口的平均响应时间从 2.3 秒降到了 45ms高峰期也不超过 100ms完美解决了性能问题。总结接口优化是一个系统性的工作需要从多个方面入手先定位慢查询优化 SQL 语句添加合适的索引避免 N1 查询使用缓存只返回需要的字段考虑使用 Redis 缓存热点数据记住过早优化是万恶之源但不优化也是万恶之源。在开发初期就要考虑到性能问题避免后期踩大坑。
http://www.zskr.cn/news/1397678.html

相关文章:

  • OPC中国是什么?一文读懂OPC开源共创社区
  • 青少年护眼大路灯推荐怎么做?西屋揽光G7如何实现学习/小憩/助眠三场景覆盖
  • Windows脚本编程避坑指南:Wscript.Shell的Run方法和环境变量那些事儿
  • 东莞硅胶制品定制完整流程,小白也能一次看懂
  • 用Python从零实现一个井字棋AI:手把手教你理解Minimax算法
  • 2026年洁净工程厂家推荐榜单:医疗洁净室/医疗器械/医药制药/食品饮料/化妆品/生物技术/手术室/GMP恒温恒湿车间最新优选 - 企业推荐官【官方】
  • Vue2 + TS,分路径参数、查询参数、装饰器组件 / Vue.extend 两种写法,同时补充类型约束、监听路由、动态路由取值。
  • 别再手动改写!用这6个嵌套式Prompt链,让ChatGPT自动生成符合出版级审校标准的创意文本
  • 为什么大额交易者与高频散户,都盯上了“交易所标准+自定义保证金”?
  • 【AI 时代软件工程师的算法图谱】04 链表操纵:指针的艺术与内存管理
  • 应对Claude官方API限流如何通过Taotoken实现无缝切换与降级
  • Light: Science Applications|从“光电转换”到“全光计算”:光纤传感的一次底层革命
  • 正规美术艺考培训的核心技术:中考美术艺考培训画室、中考美术艺考集训画室、美术艺考培训机构、美术艺考培训画室、美术艺考校考培训机构选择指南 - 优质品牌商家
  • 【技术判断力:法则一】3、如何找到唯一且正确的架构目标?4步定目标+6问判方案+实战案例
  • 为什么 Chunk(分块)策略,会决定 RAG 的效果上限?
  • 20260127-AIDeepSeek-ailwxz-e-18219-哪个AI工具写论文比较好?实测8款AI论文生成工具,图表公式+AI率+知网查重!-101213
  • 2026成都打印机租赁:成都周边打印机出租、成都周边打印机租赁、成都彩色打印机出租、成都打印机出租公司推荐、成都打印机出租哪家好选择指南 - 优质品牌商家
  • 2026年Q2邢台地区商砼站直销厂商盘点与选型指南 - 2026年企业资讯
  • 一文读懂AI智能体时代的OPC开源共创社区
  • PICT成对测试工具:如何用数学思维减少80%测试用例的终极指南
  • 浏览器端敏感信息检测实践:Hx0 数据卫士(Hx0 DataGuard)功能梳理与使用体会
  • 2026优质矩形不锈钢管供应公司TOP10推荐:方形不锈钢管、无缝不锈钢管、焊接不锈钢管、矩形不锈钢管、碳钢管件选择指南 - 优质品牌商家
  • 硬件知识 cadence16.6 导入log 的笔记及其他问题
  • 2026现阶段西安废线路板回收平台可靠合作方深度解析 - 2026年企业资讯
  • 阿里 Qwen3.7-Max 编程能力飙升至全球第二!Code Arena 盲测 1541 分,超越 Claude Opus 4.6
  • ESP32-CAM + YOLOv5实战:手把手教你搭建低成本智能监控(附Python服务端完整代码)
  • 影刀RPA店群自动化声明式配置管理:从命令式脚本到期望状态调和
  • Day36
  • 构建可扩展后端系统:事件驱动架构与消息队列应用
  • 2026夏季纯棉文化衫新趋势:定制你的个性清凉,穿出专属团队风采