Java后端服务接口性能优化常用技巧

接口性能优化常用技巧

  • 前言
    • 1.数据库索引
    • 2.慢SQL优化
    • 3.异步执行
    • 4.批量处理
    • 5.数据预加载
    • 6.池化技术(多线程)
    • 8.事件回调机制
    • 9.串行改为并行调用
    • 10.深度分页问题

前言

对于高标准程序员来说提供高性能的服务接口是我们所追求的目标,以下梳理了一些提升接口性能的技术方案,希望对大家有所帮助。

1.数据库索引

当接口响应慢时,我们可能会去排查是否是数据库查询慢了,进而会去关注数据库查询优化,而索引优化是代价最小的且效果很明显的优化方式。索引优化主要从以下几个角度考虑:

  • SQL是否添加索引?
  • 索引是否生效?
  • 索引设计是否合理?

1.1 SQL是否添加索引
在开发阶段就要考虑数据库表的索引设计,对于一些经常作为检索条件、order by、group by 后面的字段,且数据区分度高的字段可以考虑创建索引。

#可以通过explain执行查询计划,查看SQL执行情况
explain select * from t_user where name like '%黄';
#也可以通过命令show create table user 检查整张表的索引情况
show create table t_user
#如果某个表忘记添加某个索引,可以通过命令添加索引
alter table t_user add index idx_name (name);

注意: 在数据量很大的表中创建索引,最好选择在业务不繁忙时间段,避免影响线上业务。

1.2 索引不生效
有时候虽然添加了索引,但是索引可能会失效,例如下面情况:

  1. 参数类型与字段类型不匹配,导致类型发生了隐式转换,索引失效
  2. 查询条件包含or
  3. like模糊查询时,模糊匹配的占位符位于条件的首部
  4. 在联合索引的场景下,查询条件不满足最左匹配原则
  5. 使用了select *(在联合索引下,尽量使用明确的查询列来趋向于走覆盖索引)
  6. 索引列参与了函数处理,会导致全表扫描,索引失效
  7. 索引列参与了运算,会导致全表扫描,索引失效
  8. 查询条件使用 not in 时,如果是主键则走索引,如果是普通索引,则索引失效
  9. 查询条件使用 is null 时正常走索引,使用 is not null 时,不走索引
  10. 查询条件使用 not exists 时,索引失效
  11. order by导致索引失效(看情况)
  12. group by索引失效
  13. 参数不同导致索引失效

1.3 索引设计是否合理

索引不是设计越多越好,设计必须要合理,例如:优先考虑设计联合索引,适当使用覆盖索引;索引个数尽量不要超过5个;索引最好选择数据区分度较高的字段,如性别太多重复字段就不适合创建索引。

2.慢SQL优化

在索引优化之后,还可以进一步优化慢SQL语句,如下梳理10条慢sql优化建议:

  1. 尽量不用select *,查询具体需要的字段
  2. 尽量减少join关联表,部分用Java代码处理
  3. 小表驱动大表,结果集最小化
  4. in和not in中元素别太多
  5. 优化group by、order by 保证走索引
  6. 字段类型要合理使用,不要都是varchar
  7. 尽量用union all 替换union
  8. 优化limit深度分页问题
  9. 多用主键和覆盖索引,尽量减少回表
  10. 多用limit或者分页,限制返回条数

3.异步执行

对于一些耗时操作或者不影响主要业务的逻辑,可以采用异步执行,来提升性能。
在这里插入图片描述
为了降低接口耗时,及时返回结果,可以把短信发送、日志写入及积分赠送通过异步执行。

类似的场景还有:用户下订单之后的消息发送及赠送积分也可以放到异步处理。

常见的异步实现:线程池、消息队列MQ、Spring注解@Async、异步框架CompletableFuture、Spring ApplicationEvent事件。

4.批量处理

数据库操作或者远程调用时,能批量操作就不要for循环调用:

  1. 我们平时一个列表明细数据插入数据库时,不要在for循环一条一条插入,建议一个批次几百条,进行批量插入,减少多次IO,建议使用Mybatis 的foreach操作,不过数量也不要一次太多(100),MP的saveBatch、或者PreparedStatement的addBatch();

  2. 同理远程调用类似,比如你查询营销标签是否命中,可以一个标签一个标签去查,也可以批量标签去查,那批量进行,效率就更高。

//反例
for(int i = 0; i < n; i++){
  singleUpdate(param)
}
//正例
batchUpdate(param);

5.数据预加载

数据预加载策略,顾名思义就是提前把部分要用到的数据,初始化到缓存(Redis)。如果你在未来某个时间需要用到某个经过复杂计算的数据,才实时去计算的话,可能耗时比较大。这时候我们可以采取预取思想,提前把可能需要的数据计算好,放到缓存中,等需要的时候,去缓存取就行。这将大幅度提高接口性能。

6.池化技术(多线程)

池化技术最常见的是线程池应用:

  1. 如果你每次需要用到线程,都去创建,就会有增加一定的耗时;

  2. 线程池可以重复利用线程,避免不必要的耗时;

  3. 池化技术不仅仅指线程池,很多场景都有池化思想的体现,它的本质就是预分配与循环使用。

8.事件回调机制

  1. 如果你调用一个系统B的接口,但是它处理业务逻辑,耗时需要10s甚至更多。然后你是一直阻塞等待,直到系统B的下游接口返回,再继续你的下一步操作吗?这样显然不合理。

  2. 我们可以采用事件回调机制,即我们不用阻塞等待系统B的接口,而是先去做别的操作。等系统B的接口处理完,通过事件回调通知,我们接口收到通知再进行对应的业务操作即可。如IO多路复用模型实现。

9.串行改为并行调用

假设我们设计一个为每个家长发送短信的接口,它需要查寻每个家长,然后再发送短信。那你是一个一个家长发送短信,还是并行调用呢?

  1. 可以使用CompletableFuture 并行调用提高性能,类似也可以使用多线程处理。

10.深度分页问题

数据库的深度分页问题,比较影响接口性能,如下所示SQL语句:

select 
    id,name,balance from account 
where 
    create_time > '2023-09-19' 
limit 100000, 10;

limit 100000,10意味着会扫描100010行,丢弃掉前100000行,最后返回10条数据。

select id,name,balance FROM account where id > 100000 limit 10;

这样的话,后面无论翻多少页,性能都会不错的,因为命中了id主键索引。但是这种方式有局限性:需要一种类似连续自增的字段,而且需要前端把上次最大值传给后端。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/409236.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux安装Zookeeper

目录 下载配置启动 下载 下载链接 https://archive.apache.org/dist/zookeeper/上传 我直接本地下好了&#xff0c;拖到对应文件夹解压&#xff0c;重命名&#xff0c;注意路径 tar -zxvf /opt/Zookeeper/apache-zookeeper-3.7.2-bin.tar.gz -C /opt/ mv /opt/apache-zookeep…

WPF真入门教程29--MVVM常用框架之MvvmLight

1、MVVM模式回顾 关于mvvm模式的基础知识&#xff0c;请看这2个文章&#xff1a; WPF真入门教程23--MVVM简单介绍 WPF真入门教程24--MVVM模式Command命令 做过VUE开发或微信小程序开发的伙伴&#xff0c;就知道MVVM模式&#xff0c;核心就是数据驱动控件&#xff0c;全栈开…

【EAI 025】Ego4D: Around the World in 3,000 Hours of Egocentric Video

Paper Card 论文标题&#xff1a;Ego4D: Around the World in 3,000 Hours of Egocentric Video 论文作者&#xff1a;Kristen Grauman, Andrew Westbury, Eugene Byrne, et al. 作者单位&#xff1a;UC Berkeley, CMU, Google 论文原文&#xff1a;https://arxiv.org/abs/2110…

【MySQL高可用集群】MySQL的MGR搭建

前情提要&#xff1a; MySQL官方在 5.7.17版本正式推出组复制&#xff08;MySQL Group Replication&#xff0c;简称MGR&#xff09;&#xff0c;使用类似 zookeeper 的多于一半原则。在一个集群由 2N1 个节点共同组成一个复制组&#xff0c;一个事务的提交&#xff0c;必须经过…

Babylonjs学习必备

基于babylonjs封装的一些功能和插件 &#xff0c;希望有更多的小伙伴一起玩babylonjs&#xff1b; 欢迎加群&#xff1a;464146715 ​ 官方文档 中文文档 Babylonjs案例分享 ​ ​

kafka生产者2

1.数据可靠 • 0&#xff1a;生产者发送过来的数据&#xff0c;不需要等数据落盘应答。 风险&#xff1a;leader挂了之后&#xff0c;follower还没有收到消息。。。。 • 1&#xff1a;生产者发送过来的数据&#xff0c;Leader收到数据后应答。 风险&#xff1a;leader应答…

Vision Mamba:使用双向状态空间模型进行高效视觉表示学习

模型效果 将DeiT和Vim模型之间的性能和效率比较&#xff0c;为了进行准确性比较&#xff0c;我们首先在IN1K分类数据集上预训练DeiT和Vim&#xff0c;然后在不同的下游密集预测任务上微调通用主干&#xff0c;即&#xff0c;语义分割、目标检测、实例分割。结果表明&#xff0c…

VIO第5讲:后端优化实践

VIO第5讲后端优化实践&#xff1a;逐行手写求解器 文章目录 VIO第5讲后端优化实践&#xff1a;逐行手写求解器1 非线性最小二乘求解流程1.1 H矩阵不满秩的解决办法1.2 H矩阵的构建1.2.1 确定维度1.2.2 构建海塞矩阵 1.3 初始化μ—LM算法1.4 求解线性方程1.4.1 非SLAM问题—求逆…

【架构】GPU架构总结

文章目录 GPU架构GPU渲染内存架构Streaming Multiprocessor(SM)CUDA CoreTensor CoreRT CoreCPU-GPU异构系统GPU资源管理模型 GPU架构演进G80 架构Fermi 架构Maxwell架构Tesla架构Pascal架构Volta 架构Turing架构Ampere 架构Hopper架构 参考文献 GPU架构 主要组成包括&#xf…

【C语言】指针初阶

正文开始之前&#xff0c;我们要记住一个东西就是&#xff1a;地址指针 目录 一、指针的解释二、指针变量和地址1、取地址操作符2、指针变量和解引用操作1、指针变量2、拆解指针类型3、解引用操作符4、注意事项 3、指针变量的大小4、指针的解引用5、void*指针 三、指针的运算1、…

【Java程序设计】【C00277】基于Springboot的招生管理系统(有论文)

基于Springboot的招生管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的招生管理系统 本系统分为系统功能模块、管理员功能模块以及学生功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、专业…

Linux——静态库

Linux——静态库 静态库分析一下 ar指令生成静态库静态库的使用第三方库优化一下 gcc -I(大写的i) -L -l(小写的l)&#xff0c;头文件搜索路径&#xff0c;库文件搜索路径&#xff0c;连接库 今天我们来学习静态库的基本知识。 静态库 在了解静态库之前&#xff0c;我们首先来…

【Linux】MySQL数据库的使用

【Linux】MySQL数据库的使用 一、访问MySQL数据库二、创建及删除库和表1、创建新的库2、创建新的表3、删除一个数据表4、删除一个数据库 三、管理表中的数据记录1、插入数据记录2、查询数据记录3、修改数据记录4、删除数据记录 四、数据库用户授权1、授予权限2、查看权限3、撤销…

C/C++暴力/枚举/穷举题目持续更新(刷蓝桥杯基础题的进!)

目录 前言 一、百钱买百鸡 二、百元兑钞 三、门牌号码&#xff08;蓝桥杯真题&#xff09; 四、相乘&#xff08;蓝桥杯真题&#xff09; 五、卡片拼数字&#xff08;蓝桥杯真题&#xff09; 六、货物摆放&#xff08;蓝桥杯真题&#xff09; 七、最短路径&#xff08;蓝…

文献阅读:Large Language Models are Null-Shot Learners

文献阅读&#xff1a;Large Language Models are Null-Shot Learners 1. 文章简介2. 方法介绍3. 实验考察 & 结论 1. 基础实验 1. 实验设计2. 实验结果 2. 消融实验 1. 小模型上的有效性2. ∅CoT Prompting3. 位置影响4. 组成内容 4. 总结 & 思考 文献链接&#xff1…

双重检查锁定与延迟初始化

双重检验锁&#xff1a;多线程下的单例模式。 懒加载模式&#xff1a;延迟初始化。

域名系统与IP地址分配

域名 域名的概述 域名是一个逻辑的概念&#xff0c;它不反映主机的物理地点 域名结构 由于数字形式的IP地址难以记忆和理解&#xff0c;为此人们采用英文符号来表示IP地址&#xff0c;这就产生了域名&#xff0c;域名长度不超过255各字符&#xff0c;每一层域名长度不超过6…

利用psutil库检查脚本是否在运行

摘要 如果要判断某一脚本是否在运行&#xff0c;可以通过psutil库获取所有进程的cmdline&#xff0c;并判断指定的文件名是否在cmdline中。 目录 1.psutil库简介 2.检查代码及说明 2.1检查思路 2.2异常捕获 2.3执行方法 1.psutil库简介 psutil 是一个跨平台&#xff08;…

算法沉淀——动态规划之简单多状态 dp 问题(上)(leetcode真题剖析)

算法沉淀——动态规划之简单多状态 dp 问题上 01.按摩师02.打家劫舍 II03.删除并获得点数04.粉刷房子 01.按摩师 题目链接&#xff1a;https://leetcode.cn/problems/the-masseuse-lcci/ 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在…

【Unity】提示No valid Unity Editor liscense found.Please active your liscense.

有两个软件&#xff0c;如果只有一个&#xff0c;点黑的不会有效果、、、、&#xff08;楼主是这个原因&#xff0c;可以对号入座一下&#xff09; 简而言之&#xff0c;就是去下载Unity Hub&#xff0c;再里面激活管理通行证 问题情境&#xff1a; 点击unity出现以下弹窗&a…