# (一):小試牛刀,統一顯示SQL語句執行時間
最近,在開發和優化一個報表型的Web項目,底層是Hibernate和MySQL。
當報表數據量大的時候,一個圖表要花4秒以上的時間。
**以下是我的分析和體會。**
**1.我首先需要知道哪些函數執行了多少時間,哪些sql花了多少時間。**
a.最笨最簡單的方法是,每一個函數的調用開始和結尾都保存開始時間startTime和結束時間endTime,? 進行計算。
b.寫一個“攔截器”,攔截每一個方法的執行,計算時間。
這個又太難了,沒啥思路。
c.想到Hibernate查詢,真正執行sql語句的方法是query.list()方法。
因此,只需要計算query.list()這個方法的執行,大概就能得出每個函數的執行時間了。
很巧的是,我寫了一個功能強大的BaseDao,大部分查詢最終歸結到了一個方法。
~~~
protected?List?executeQueryList(String?hql,?Map?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](http://fansunion.cn/articles/2843)