最近帮忙公司的几个项目组进行了不同方面的性能优化,发现几个项目都出现了一些共性的问题。这里写一篇文章,总结一下这几类问题,以及其对应的解决方案。方便其它项目组参考。

常见问题一:打开页面非常慢,有的项目打开一个页面竟然要 20 多秒。


优化步骤:

  1. 降低每一个页面的请求数:使用浏览器跟踪打开页面后所有的请求,并逐一排查,把没有必要向服务端发起的请求优化掉,减少 Round Trip 次数。
  2. 针对每一个请求进行优化:对请求逐一排查,看看分别是哪些请求占用了较多的时间。 
    如果该请求是 JS 文件,则考虑使用压缩版本(例如正在使用的 EXTJS,应该使用 ext-all.js 1.9M,而不是 ext-all-debug.js 4.5M)。 
    静态资源要尽量启用缓存。
  3. 将每次请求所对应的数据库访问次数降低到最低:这一步属于后端优化。 
    每一个请求到达服务端后,都会做一系列的操作,例如:初始化当前用户、角色、权限、当前模块、业务逻辑、日志等。 
    对于前四个操作,往往是所有页面都需要初始化的,那么我们需要使用 Session 或 Cache 等技术来优化,以防止每次请求都重新访问数据库。 
    对于业务逻辑、日志等,我们主要解决的是《ORM 中的 N+1 问题》、优化掉多余的数据库访问(需要记住,每一次数据库访问,其实都是一次远程访问)。
  4. 另外,Web 页面的前端优化,还可以参考《 YAHOO Web 优化的 14 条法则》。

常见问题二:单条 SQL 语句执行较慢


在数据量较大的情况下,一些 SQL 语句执行得非常慢。

优化步骤:

  1. 是否 SQL 本身有性能问题?
  2. 是否建立了表分区? 
    http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html 
    http://blog.csdn.net/hijiankang/article/details/9173877
  3. 是否对主要查询的字段建立了索引?
  4. 测试数据是否有效?(尽量按照真实场景来准备测试数据)
  5. 是否需要限制用户的数据查询范围?
  6. 是否需要优化业务结构? 
    是否真的需要为用户提供一个查看几十万页的数据的页面?这样的数据对于用户来说,往往是没用的。我们应该在功能模块方面重新设计?
  7. 不要使用 JOIN,而是使用 IN 语句。
  8. 不要查询全字段,而是只查询 ID。

例如,下面这个 SQL,在压力测试 1000 万行数据时,已经需要 8 秒左右:

SELECT * FROM
(SELECT T.*, ROWNUM RNFROM (
SELECT * FROM "T_PRIMITIVEDETAIL" "T0" WHERE "T0"."ORDERGOODSDATE" >= :p0 AND "T0"."ORDERGOODSDATE" <= :p1 AND "T0"."CORPORATION" = :p2 AND "T0"."DBI_ISPHANTOM" = :p3 ORDER BY "T0"."ID" ASC ) T WHERE ROWNUM <= 5000010 ) WHERE RN >= 5000000 --Parameters:2016/5/1 0:00:00,2016/5/31 23:59:59,"惠州酷友网络科技有限公司","0"

ID 列和 ORDERGOODSDATE 列都是建立了索引的,同时也为 ORDERGOODSDATE 列建立了表分区。经过几次测试,发现通过索引列排序进行查询速度还是较慢(索引 Id 列:首次5秒,后面都是2.3秒;有索引的时间列:6秒;不排序:2秒)。

同时,我们还对分页 SQL 进行的测试。目前有三种较为通用的分页格式:

1.根据ROWID来分 
select * from t_xiaoxi where rowid in( 
  select rid from ( 
    select rownum rn,rid from( 
     select rowid rid,cid from 
     t_xiaoxi  order by cid desc 
    ) where rownum<10000 
  ) where rn>9980 

order by cid desc; 
2.按分析函数来分 
select * from ( 
  select t.*,row_number() over(order by cid desc) rk from t_xiaoxi t 
) where rk<10000 and rk>9980; 
3.按ROWNUM来分 
select * from( 
  select t.*,rownum rn from( 
    select * from t_xiaoxi order by cid desc 
  ) t where rownum<10000 
) where rn>9980;

结果发现,原来的分页格式,效率是最高的。下面的 SQL 查询需要 4 秒:

select * from ( 
  select t.*,row_number() over(order by id ASC) rk from T_ENTERPRISETRANSACTION t 
) where rk <= 5000010 and rk >= 5000000

由于我们的分页 SQL 是自动生成的,所以格式方面我们要保留一定的通用性,同时性能不能太差。所以还是决定继续保留原有的格式。

前面几个优化方案没有成功。我们就看了一下测试人员插入的一千条数据。原来这些数据的时间都是同一天的!!!造成了分区和索引失效。将数据按照真实场景录入后,不到 1s 就查询出来了。

另外,第 6 条:有 50 万页数据的页面,不应该设计给客户看到。所以我让项目组的同这考虑是否需要删除这个页面,换一种实现方案。

第8条,不查全字段,只查 ID:测试后,也有了比较明显的效果。

SELECT ID FROM
(SELECT T.*, ROWNUM RNFROM (
SELECT ID FROM "T_ENTERPRISETRANSACTION" "T0" --order by T0.Id desc --order by T0.DBI_CreatedTime --order by T0.tradeDate ) T WHERE ROWNUM <= 5000010 ) WHERE RN >= 5000000 --0.6秒 SELECT * FROM "T_ENTERPRISETRANSACTION" "T0" WHERE ID IN (7853679,7853680,7853681,7853682,7853683,7853684,7853685,7853686,7853687,7853688,7853689) --0.1秒

一共只需要 0.7 秒。

常见问题三:大数据导入性能优化


公司产品的一个重要模块是一个数据导入引擎。基于 WF4 引擎,配合一定的活动,来实现从文件到数据库的导入。即:读取文件 –> 大量数据格式转换逻辑 & 大量业务逻辑 –> 导入数据库。

由于逻辑非常复杂,所以我们并没有把这些逻辑放到数据库中去编写存储过程,而是基于内存中的领域实体来执行业务逻辑。

对于此程序的优化步骤:

  1. 通过性能监控工具,找到性能损耗的核心位置,再针对该位置出方案进行优化。 
    这一步应该作为第一个步骤。开发者在对性能进行优化时,往往出现“想当然”地去分析、优化的行为,最终是花费了时间也没有优化到点上!所以这里首重提出这一步骤。先让工具去帮我们找到这些核心位置!
  2. 降低数据库访问次数。(此项检查是所有数据库访问程序的首要优化方案,也是最容易出现问题的地方)。 
    1.1 解决 ORM 中的 N+1 问题。 
    1.2 在内存中一次性准备好数据后,再插入到数据库中。 
    1.3 对于导入大数据量到数据库中,采用批量导入方案,而非逐条导入方案。
  3. 多线程技术。 
    由于数据导入程序是 IO 密集型 + CPU 密集型操作,但是二者的运行阶段不同。所以合理地采用多线程,可以大大提升执行效率。 
    使用多线程时,要注意线程安全的问题:尽量不要有太多的共享资源(文件、数据库中的行);共享资源要加锁(文件加锁、内存加锁、数据库事务(事务的级别))。 
    另外,提前为各个线程准备好一些共用的数据,也可以优化一些不必要的 IO。
  4. 优化核心大数据的循环,以及嵌套循环的核心循环中的代码即可。这些位置的代码,需要处处小心,优化到极致。 
    核心循环中,不要用 LINQ To Object:一个 Linq To Object 操作,至少生成了三个轻量级对象:一个委托、一个实现 IEnumerable 接口的对象,以及遍历集合时,生成的一个 Enumerator。 
    核心循环中,要尽量减少循环的次数。例如:1000万数据和100万数据做循环匹配,不优化的循环就需要执行 1000万*100万次。所以我们需要引入一些算法来优化不必要的循环次数。 
    只需要优化核心循环,不需要优化所有的代码。LINQ To Object 该用的时候,还要用。                                  转载自 胡庆访http://zgynhqf.cnblogs.com/ ]

性能调优常见问题与方案相关推荐

  1. 深入理解Java虚拟机:Jvm性能调优

    本篇内容包括:Jvm 性能调优简介:根据需求目标进行 Jvm 调优规划(即 调优的目标.调优的步骤):Jvm 调优参数.命令.工具:以及 Java 中的内存泄露问题的详解- 一.Jvm 性能调优简介 ...

  2. Kafka跨集群迁移方案MirrorMaker原理、使用以及性能调优实践

    序言 Kakfa MirrorMaker是Kafka 官方提供的跨数据中心的流数据同步方案.其实现原理,其实就是通过从Source Cluster消费消息然后将消息生产到Target Cluster, ...

  3. OA性能调优方案(二)

    访问 nginx 状态监控页: 双击 stop.bat 关闭新 nginx 替换旧 nginx 将执行文件由 nginx.exe 重命名为 officeNginx.exe,这样 OA 就可以帮新ngi ...

  4. mysql性能调优 高可用_MySQL性能调优与架构设计——第 17 章 高可用设计之思路及方案...

    第 17 章 高可用设计之思路及方案 前言: 数据库系统是一个应用系统的核心部分,要想系统整体可用性得到保证,数据库系统就不能出现任何问题.对于一个企业级的系统来说,数据库系统的可用性尤为重要.数据库 ...

  5. 【网站架构】Nginx负载均衡宕机怎么办?Nginx性能调优、集群、高可用方案

    ​ 大家好,欢迎来到停止重构的频道. 本期,我们讨论Nginx的性能调优. Nginx一般是作为网站系统的反向代理或负载均衡,但这里有一个问题,负载均衡可以绑定多个后端服务器. 一个后端服务器宕机后, ...

  6. 《Java后端性能调优实战方案手册》,看完至少阿里P7

    之前有朋友说,"我们公司的系统从来都没有经过性能调优,集成测试没问题后就上线了,上线后也几乎没出现过性能问题."其实没遇到性能问题不代表程序不存在性能问题,只能说明系统的访问量有点 ...

  7. Docker中应用的性能调优指南(一)- 先谈谈容器化性能调优

    摘要: 前言 性能调优是一个老生常谈的话题,通常情况下,一个应用在上线之前会进行容量规划.压力测试并进行验证,而性能调优则是在容量规划与验证结果之间出现差异时会进行的必然手段.从某种角度来讲,性能调优 ...

  8. 中间件业务在网易轻舟容器平台的性能调优实践

    随着业务容器化的推进,经常有客户抱怨应用 QPS 无法和在物理机或者云主机上媲美,并且时常会出现 DNS 查询超时.短连接 TIME_OUT.网络丢包等问题,而在容器中进行调优与诊断的效果因为安装工具 ...

  9. 大数据技术之_19_Spark学习_07_Spark 性能调优 + 数据倾斜调优 + 运行资源调优 + 程序开发调优 + Shuffle 调优 + GC 调优 + Spark 企业应用案例

    大数据技术之_19_Spark学习_07 第1章 Spark 性能优化 1.1 调优基本原则 1.1.1 基本概念和原则 1.1.2 性能监控方式 1.1.3 调优要点 1.2 数据倾斜优化 1.2. ...

最新文章

  1. python标准库介绍——23 UserString 模块详解
  2. 【GAN】GAN 也可以大幅压缩,来自MIT 韩松团队的最新研究!算力消耗不到1/9,现已开源!...
  3. JAVA正则表达式:Pattern类与Matcher类详解(转)
  4. ReentrantLock 源码分析
  5. Strom集群安裝,Python安裝,Strom配置,Strom常用命令
  6. spwm逆变器双极性matlab教程,三相逆变器双极性SPWM调制技术的仿真(论文资料).doc...
  7. php程序里如何实现图片翻页,php图片上传代码一例-php 生成翻页链接(页码)列表的...-带多种分页方式的php分页类_169IT.COM...
  8. django ajax 简书,Django_ajax
  9. Java模拟事务Demo
  10. dash 和 bash 切换
  11. flex vue 垂直居中居上_推荐几种在移动端实现垂直居中的方法
  12. ubuntupython连接数据库_Ubuntu中python的mysql操作
  13. 使用python中的networkx来生成一个图
  14. 历日 [宋] 许月卿
  15. C++11的dynamic_cast
  16. js禁止退出当前页面
  17. JSP简介和会话技术
  18. LayoutLM: Pre-training of Text and Layout for Document Image Understanding
  19. typora+gitee图床
  20. 车载系统升级、“特饭”会员品牌上线,解读新特背后的互联网产品逻辑

热门文章

  1. 冒号课堂 编程范式与OOP思想
  2. Spark在Windows下的环境搭建
  3. 一篇文章搞懂JavaScript运行机制
  4. 数据库MYSQL学习系列三
  5. nodejs windows 安装过程
  6. 用Node.js 写web框架(番外)
  7. The user specified as a definer ('root'@'%') does not exist
  8. FFT2 图像二维FFT含义解释
  9. IT菜鸟,希望大家赐教
  10. 拿什么留住你,我的程序员