首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

一个Web表格项目的性能分析和优化实践(一)

2013-10-30 
一个Web报表项目的性能分析和优化实践(一) 最近,在开发和优化一个报表型的Web项目,底层是Hibernate和MySQL

一个Web报表项目的性能分析和优化实践(一)

 最近,在开发和优化一个报表型的Web项目,底层是Hibernate和MySQL。

 当报表数据量大的时候,一个图表要花4秒以上的时间。

  以下是我的分析和体会。
 
 1.我首先需要知道哪些函数执行了多少时间,哪些sql花了多少时间。
  a.最笨最简单的方法是,每一个函数的调用开始和结尾都保存开始时间startTime和结束时间endTime,  进行计算。
  b.写一个“拦截器”,拦截每一个方法的执行,计算时间。
    这个又太难了,没啥思路。
  c.想到Hibernate查询,真正执行sql语句的方法是query.list()方法。
   因此,只需要计算query.list()这个方法的执行,大概就能得出每个函数的执行时间了。
   很巧的是,我写了一个功能强大的BaseDao,大部分查询最终归结到了一个方法。
   
 

  protected List executeQueryList(String hql, Map<String, Object> params,   Integer firstResult, Integer maxResults) {        Query query = createQuery(hql, params);        if (firstResult > 0) {            query.setFirstResult(firstResult);        }        if (maxResults > 0) {            query.setMaxResults(maxResults);        }        Date startTime = new Date();        List list = query.list();        String costTime = CostTimeUtils.getCostTime(startTime);        println(query, costTime);        return list;    }


这样,我只需要在一个地方,计算耗费的时间,就大致知道了每个方法和sql语句的实际执行时间了。

2.看了下Hibernate打印出来的SQL语句和程序源码,发现执行的数据查询太多,平均每个0.02到0.05,少数需要0.34,0.35。

  一个0.02s,查询几十次到上百次,花费的时间就多了。

3.少数查询要0.34,0.35, 应该是网络引起的??

  后来,经过自己的分析,与同事好友的交流,可能的原因是查询的字段太多导致的,Hibernate通过反射向Java实体对象填充值,也需要花费一些时间。

  然后,我又想到,TReport这个表字段确实不少,更关键的是我们把一些图表的信息存放在这个表里的longblob类型的字段。

4.字段的数据类型有影响么?

 有些小数据量的字段,用的是longtext。

 逐个将其统一为varchar。

5.统一Hibernate用法,方便查看HQL/SQL语句的执行时间。

  以前我对项目进行重构过,现在大部分的查询都要经过BaseDao中的一个查询方法,

Date startTime = new Date(); List list = query.list(); String costTime = CostTimeUtils.getCostTime(startTime); println(query, costTime);


但是,还有很多查询没有经过这里,导致有的SQL执行时间,不方便查看。

6.最初,想查看每个方法执行时间的时候,我首先想到的是找一个这样的工具。

  不过,最后还是没能找到。

  JProfile之类的工具,还没怎么用过,抽空再学习和应用下。

7.针对查询用到的SQL语句,建立合适的索引。

  这个还没有头绪,正在摸索中。

8.查询方法执行效率不高?

public Treport getReportById(Integer reportId) {        String hql = "from Treport where reportId = :reportId";        Treport report = super.executeQueryUnique(hql, "reportId", reportId);        return report;    }


  有的地方,根据HQL语句查询没有必要。

  Treport表的主键就是reportId,可以使用Hibernate的get(id)来查。

  多写了代码,维护麻烦,效率还不高。

  我的感觉是:自己构造HQL语句查询,没有Hibernate的get方法效率高,没有具体去测试。
 

不足之处

上文都是一些比较浅显的分析,更为详细的优化过程,最近几周正在实践之中。

后续几篇,将详细描述分析和优化过程。

原文参见:http://FansUnion.cn/articles/2843

1楼jiangfullll46分钟前
我没有仔细看你写的代码,但是看你的标题之后,我处理的流程会是:n在程序没有错的情况下,n一、看hql语句是否被滥用了,该用select col from table的写成select * from table了n二、看where子句的执行顺序,一般最后面的条件是过滤掉大部分数据的条件,以次类推。看看是否改用join的地方使用了select col from table where col in (select ...)的语句,检查视图的sql语句n三、给表的列适当建立索引n四、再高级一些的就是读写分离或者mysql集群了(我也木有搞过)
Re: FansUnion33分钟前
回复jiangfulllln1."该用select col from table的写成select * from table了"n查询了过多的字段,这种情况是存在的。n这个晚点优化。n2.看where子句的执行顺序。n咱们用的大多数 关联查询,很少用子查询。n这个晚点优化。nn3.给表的列适当建立索引。n 这个是本周的重点。n 我们有一个数据库,全是数据和维度,有数据更新的时候,才会插入。n 索引会比较有效。n4.读写分离或者mysql集群。n 等正式上线,数据量大了之后,应该会弄。n 我也不熟悉,需要边学边用,不会的就去问boss或者公司相关大牛。nn多谢你的分享哦。n更多实践经验,看这个系列的后几篇额。

热点排行