发布日期:2023-10-30 05:59 点击次数:124
接口性能优化关于从过后端建树的同学来说,确定再熟识不外了,因为它是一个跟建树谈话无关的世界问题。
该问题说浮浅也浮浅,说复杂也复杂。
有时代,只需加个索引就能惩办问题。 有时代,需要作念代码重构。 有时代,需要加多缓存。 有时代,需要引入一些中间件,比如mq。 有时代,需要需要分库分表。 有时代,需要拆分处事。 等等。。。导致接口性能问题的原因千奇百怪,不同的神情不同的接口,原因可能也不一样。
本文我追思了一些行之有用的,优化接口性能的目的,给有需要的一又友一个参考。
1.索引接口性能优化巨匠第一个思到的可能是:优化索引。
皇冠管理网网址没错,优化索引的本钱是最小的。
皇冠博彩平台您提供多样化博彩游戏赛事直播,全面、优质博彩攻略技巧分享,您博彩游戏中尽情享受乐趣收益。平台安全稳定,操作简便,充值提款便捷,您提供最佳博彩体验最高博彩收益。你通过搜检线上日记或者监控发达,查到某个接口用到的某条sql语句耗时比拟长。
这时你可能会有底下这些疑问:
该sql语句加索引了没?
加的索引成效了没?
mysql选错索引了没?
1.1 没加索引sql语句中where条目的要道字段,或者order by背面的排序字段,忘了加索引,这个问题在神情中很常见。
神情刚运转的时代,由于表中的数据量小,加不加索引sql查询性能分散不大。
其后,跟着业务的发展,表中数据量越来越多,就不得不加索引了。
皇冠体育
不错通过号召:
show index from `order`;
能单独搜检某张表的索引情况。
也不错通过号召:
show create table `order`;
搜检整张表的建表语句,内部一样会显现索引情况。
通过ALTER TABLE号召不错添加索引:
zh皇冠信用网下载ALTER TABLE `order` ADD INDEX idx_name (name);
也不错通过CREATE INDEX号召添加索引:
CREATE INDEX idx_name ON `order` (name);
不外这里有一个需要贯注的场所是:思通过号召修改索引,是不行的。
当今在mysql中淌若思要修改索引,只可先删除索引,再重新添加新的。
删除索引不错用DROP INDEX号召:
ALTER TABLE `order` DROP INDEX idx_name;
用DROP INDEX号召也行:
DROP INDEX idx_name ON `order`;1.2 索引没成效
通过上头的号召咱们仍是能够证明索引是有的,但它成效了没?此时你内心偶然会冒出这么一个疑问。
那么,何如搜检索引有莫得成效呢?
答:不错使用explain号召,搜检mysql的推行意象打算,它会显现索引的使用情况。
举例:
explain select * from `order` where code='002';
扫尾:
通过这几列不错判断索引使用情况,推行意象打算包含列的含义如下图所示:
淌若你思进一步了解explain的详备用法,不错望望我的另一篇著作《explain | 索引优化的这把绝世好剑,你确凿会用吗?》
说真话,sql语句莫得走索引,舍弃莫得建索引以外,最大的可能性是索引失效了。
底下说说索引失效的常包涵因:
淌若不是上头的这些原因,则需要再进一步排查一下其他原因。
1.3 选错索引此外,你有莫得遭受过这么一种情况:明明是并吞条sql,独一入参不同资料。有的时代走的索引a,有的时代却走的索引b?
本赛季,罗德里作为曼城的主力后腰,在各项赛事出场56次,其中52次作为主力。除了出色地完成了防守端的任务外,罗德里还打进4球助攻7次。本场比赛的进球也是他整个赛季最重要的进球。
买彩票没错,有时代mysql会选错索引。
必要时不错使用force index来强制查询sql走某个索引。
至于为什么mysql会选错索引,背面有特意的著作先容的,这里先留点悬念。
2. sql优化淌若优化了索引之后,也没啥扫尾。
接下来试着优化一下sql语句,因为它的改形本钱联系于java代码来说也要小得多。
底下给巨匠列举了sql优化的15个小本事:
由于这些本事在我之前的著作中仍是详备先容过了,在这里我就不深切了。
更详备的内容,不错看我的另一篇著作《聊聊sql优化的15个小本事》,征服看完你会有许多收货。
3. 资料调用许多时代,咱们需要在某个接口中,欧博博彩官网调用其他处事的接口。
比如有这么的业务场景:
在用户信息查询接口中需要复返:用户称呼、性别、等第、头像、积分、成长值等信息。
宝马会现金网而用户称呼、性别、等第、头像在用户处事中,积分在积分处事中,成长值在成长值处事中。为了汇总这些数据息争复返,需要另外提供一个对外接口处事。
于是,用户信息查询接口需要调用用户查询接口、积分查询接口 和 成长值查询接口,然后汇总和据息争复返。
调用历程如下图所示:
调用资料接口总耗时 530ms = 200ms + 150ms + 180ms
彰着这种串行调用资料接口性能诟谇常不好的,调用资料接口总的耗时为所有的资料接口耗时之和。
那么何如优化资料接口性能呢?
3.1 并行调用上头说到,既然串行调用多个资料接口性能很差,为什么不改成并行呢?
如下图所示:
博彩平台游戏调用资料接口总耗时 200ms = 200ms(即耗时最长的那次资料接口调用)
在java8之前不错通过收场Callable接口,得回线程复返扫尾。
银河娱乐集团有限公司java8以后通过CompleteFuture类收场该功能。咱们这里以CompleteFuture为例:
public UserInfo getUserInfo(Long id) throws InterruptedException, ExecutionException { final UserInfo userInfo = new UserInfo(); CompletableFuture userFuture = CompletableFuture.supplyAsync(() -> { getRemoteUserAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture bonusFuture = CompletableFuture.supplyAsync(() -> { getRemoteBonusAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture growthFuture = CompletableFuture.supplyAsync(() -> { getRemoteGrowthAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture.allOf(userFuture, bonusFuture, growthFuture).join(); userFuture.get(); bonusFuture.get(); growthFuture.get(); return userInfo; }
温馨教唆一下,这两种方法别忘了使用线程池。示例中我用到了executor,示意自界说的线程池,为了防护高并发场景下,出现线程过多的问题。
3.2 数据异构上头说到的用户信息查询接口需要调用用户查询接口、积分查询接口 和 成长值查询接口,然后汇总和据息争复返。
那么,咱们能不可把数据冗余一下,把用户信息、积分和成长值的数据息争存储到一个场所,比如:redis,存的数据结构等于用户信息查询接口所需要的内容。然后通过用户id,径直从redis中查询数据出来,不就OK了?
淌若在高并发的场景下,为了提高接口性能,资料接口调用概况率会被去掉,而改成保存冗尾数据的数据异构有辩论。
皇冠客服飞机:@seo3687但需要贯注的是,淌若使用了数据异构有辩论,就可能会出现数据一致性问题。
用户信息、积分和成长值有更新的话,大部分情况下,会先更新到数据库,然后同步到redis。但这种跨库的操作,可能会导致双方数据不一致的情况产生。
4. 重迭调用重迭调用在咱们的日常使命代码中不错说随地可见,但淌若莫得礼貌好,会绝顶影响接口的性能。
不信,咱们全部望望。
4.1 轮回查数据库有时代,咱们需要从指定的用户合股中,查询出有哪些是在数据库中仍是存在的。
收场代码不错这么写:
public List<User> queryUser(List<User> searchList) { if (CollectionUtils.isEmpty(searchList)) { return Collections.emptyList(); } List<User> result = Lists.newArrayList(); searchList.forEach(user -> result.add(userMapper.getUserById(user.getId()))); return result; }
这里淌若有50个用户,则需要轮回50次,去查询数据库。咱们王人知谈,每查询一次数据库,等于一次资料调用。
淌若查询50次数据库,就有50次资料调用,这诟谇常耗时的操作。
那么,咱们何如优化呢?
具体代码如下:
public List<User> queryUser(List<User> searchList) { if (CollectionUtils.isEmpty(searchList)) { return Collections.emptyList(); } List<Long> ids = searchList.stream().map(User::getId).collect(Collectors.toList()); return userMapper.getUserByIds(ids); }
提供一个证据用户id合股批量查询用户的接口,只资料调用一次,就能查询出所有的数据。
这里有个需要贯注的场所是:id合股的大小要作念狂妄,最佳一次不要肯求太多的数据。要证据践诺情况而定,冷落礼貌每次肯求的纪录条数在500以内。
4.2 死轮回有些小伙伴看到这个标题,可能会感到有点无意,死轮回也算?
代码中不是应该幸免死轮回吗?为啥照旧会产存一火轮回?
有时代死轮回是咱们我方写的,举例底下这段代码:
while(true) { if(condition) { break; } System.out.println("do samething"); }
这里使用了while(true)的轮回调用,这种写法在CAS自旋锁中使用比拟多。
当知足condition等于true的时代,则自动退出该轮回。
淌若condition条目绝顶复杂,一朝出现判断不正确,或者少写了一些逻辑判断,就可能在某些场景下出现死轮回的问题。
出现死轮回,概况率是建树东谈主员东谈主为的bug导致的,不外这种情况很容易被测出来。
还有一种粉饰的比拟深的死轮回,是由于代码写的不太严谨导致的。淌若用泛泛数据,可能测不出问题,但一朝出现极端数据,就会立即出现死轮回。
4.3 无尽递归淌若思要打印某个分类的所有父分类平博龙虎斗,不错用雷同这么的递归措施收场:
public void printCategory(Category category) { if(category == null
上一篇:没有了
下一篇:香港六合彩色碟客服电话_家喻户晓, 东谈主急了什么王人能作念出来, 除了数学