栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java-性能优化篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java-性能优化篇

java-性能优化篇

因为一次公司倒闭,感悟到人生不容易,选择以物联网做副业,从事物联网卡代理,希望认识更多好朋友,合作共赢.

(当你身上有了担子,你就会发现,收入来源太单一,会使你没有安全感!)

公司项目已经完成阶段性上线,目前正在对残留的一些性能问题进行优化,今天针对优化过程中的一系列流程进行整理,希望能帮助到各位。我们单纯的先从软件层面出发(硬件的说实话,不是很good at)

第一步:分析性能问题

首先,可以依据类似听云这类全链路日志,可以看到整个接口的调用链路以及响应时间。每个sql语句的耗时以及后续api的调用时长。

第二步:分块优化

大多数情况下,性能问题是由于一些慢sql导致的,那么接下来,面试时问到的一些关于sql优化的方案就可以派上用场了。

SQL层面

    从建表出发

    1.1 CHAR是可变长字符串,VARCHAR是固定大小,字符类型尽量根据实际预存值大小设置,否则会浪费空间;

    1.2 尽量避免出现null值,给缺省值(默认值);

    1.3 能用int类型的不要用varchar或者char类型,否则mysql比较相等时,会默认每个字符依次匹配;

    从索引的角度出发
    2.1 是否添加必要索引 ?
    所谓必要列的索引,指的是不会频繁更新的,与其他表关联的,小的字段;

    2.2 ** 执行计划中查看是否命中索引?**
    有时存在sql优化器自动选取较优索引,如果不是实际最有,我们可以用**use index(index_name)**指定使用某个索引;

    2.3 如果存在符合索引,那么请注意where后面的过滤条件的先后顺序是否遵循索引的最左原则;

    从sql语句出发

    3.1 避免大数据量in查询(一般超过200,索引就显得力不从心了);

    3.2 能用关联查询的尽量不用子查询(子查询会生成临时表,表的创建和销毁有性能开销);

    3.3 如果存在类似union查询两端都需要基于某张表做各自的统计查询,这个时候**CTE(with as)**语句就很nice;

    with temp_table as(
    select id, name ,age
    from user
    where schoole_id =""
    )
    select * from temp_table;
    通过with as创建公用表表达式,后续的sql都可以直接用已经生成(过滤后)的公用表做操作。
    

    3.4 如果join两边的表数据量特别大,并且过滤条件能有效的过滤掉很大一部分数据,可以尝试先子查询过滤在join(理论上)

代码层面

    如果存在分页查询,分页查询时自定义查询总数语句,去除多余表关联;
    例如:
    传来岗位集合和考试id,查询每个岗位下的考试试题情况,可以直接查询考试下的题目数量*岗位集合size=总数,无需在关联 多余的表,只需要关心最细粒度的分页数据;

    如果需要查询没有依赖关系的多个数据,考虑多线程异步查询,耗时取多个任务中的最大值(countdownlatch);、

    CountDownLatch countDownLatch = new CountDownLatch(4); // 开启4个线程异步执行查询
    try{
                   // 第一次考試信息
               	erver.getFirstInfo(examInfoDOMap,orgId,uemIdsList,countDownLatch);
                    // 最高分信息
            	erver.getTopInfo(topUserExamInfoDOHashMap,orgId,uemIdsList,countDownLatch);
                    // 平均分&考试次数
                erver.getOtherInfo(eaCntAndAvgScoreMap,orgId,uemIdsList,countDownLatch);
                    // 正确答案
                erver.getQuesCorrectAnswer(answerDetailMap,orgId,uemIdsList,countDownLatch);
                    countDownLatch.await(); // 主线程等待4个线程执行结束才继续执行
                }catch (Exception e){
                    e.printStackTrace();
     }
    
    
        
        @Async
        public void getQuesCorrectAnswer(Map> answerDetailMap,
                String orgId,List uqIds,CountDownLatch countDownLatch,) {
            try {
               // --------
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                countDownLatch.countDown(); // finally一定要执行countdown(),否则会阻塞
            }
        }
    

    针对sql较多的任务,并行流很ok,针对计算任务较多的,线程数不宜过多,会造成额外的cpu切换开销;

    并行流操作list,map之类的,切记一定要用CopyOnArrayList、ConcurrentHashMap之类的线程安全的集合,否则会空指针;

    后续补充。。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号