浏览 2719 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2005-10-03
引用 Optimization is not much use without monitoring and access to performance numbers. 在Hibernate3 Reference 20.6节中,提到了Hibernate3可以利用JMX收集系统运行时的一些数据,从而给出一些可供优化系统性能的数据。 当是最简单的方式莫过于直接使用 SessionFactory.getStatistics() 来获取这些统计信息,当然前提是你要在hibernate的配置文件中把 hibernate.generate_statistics 设为 true。 写一个定时任务: [code:1] Statistics stats = sessionFactory.getStatistics(); //total statistics stats.logSummary(); String[] clazz = stats.getEntityNames(); //entity statistics if (clazz != null && clazz.length > 0) { for (int i=0;i<clazz.length;i++) { EntityStatistics entityStats = stats.getEntityStatistics(clazz[i]); logger.info(clazz[i]); logger.info("inserted : " + entityStats.getInsertCount()); logger.info("updated : " + entityStats.getUpdateCount()); logger.info("deleted : " + entityStats.getDeleteCount()); logger.info("loaded : " + entityStats.getLoadCount()); } } String[] queries = stats.getQueries(); //queries statistics if (queries != null && queries.length > 0) { for (int i=0;i<queries.length;i++) { QueryStatistics queryStats = stats.getQueryStatistics( queries[i] ); logger.info(queries[i]); logger.info("ExecutionAvgTime : " + queryStats.getExecutionAvgTime() ); logger.info("ExecutionMinTime : " + queryStats.getExecutionMinTime() ); logger.info("ExecutionMaxTime : " + queryStats.getExecutionMaxTime() ); logger.info("ExecutionCount : " + queryStats.getExecutionCount() ); logger.info("ExecutionRowCount : " + queryStats.getExecutionRowCount() ); } } //clear stats.clear(); [/code:1] 把你的log4j配置到这个定时器,不过 logger 必须是: [code:1] private static final Log logger = LogFactory.getLog("org.hibernate.stat.StatisticsImpl"); [/code:1] 否则,你不能看到 stats.logSummary() 的统计信息,当然,你也可以用自己的log记录stats.toString(),结果一样,只不过格式不同而已。 然后,每隔一段时间你就会得到一个统计报告,里面有二级缓存的使用情况,访问数据库的次数,执行事务的次数,每个实体的增、删、改、查次数,每个运行过的HQL的执行时间。 扩展: 默认的Hibernate3只能统计HQL和native SQL,无法统计对象载入及由此产生的Fetch的语句的性能,以及Criteria查询API所产生的语句的性能。 Gavin解释了理由:http://forum.hibernate.org/viewtopic.php?t=948329 由此可见Hibernate Team对于由他们的程序所生成的SQL语句的性能多么自信,呵呵 但是我觉得,如果仅仅是为了系统架构的考虑,和对Hibernate的信心,还不足以使我放弃统计其他的SQL语句。所以,修改了Hibernate3的代码: org.hibernate.loader.Loader : [code:1] protected String getQueryIdentifier() { return null; } [/code:1] to [code:1] protected String getQueryIdentifier() { return getSQLString(); } [/code:1] 因为Loader本来只在载入对象时运行,而运行HQL是由继承它的子类完成,而Hibernate Team不认为需要统计由此产生的SQL语句,所以直接返回空,使得统计分析器忽略这些SQL语句。而这个修改,使得所有的SQL以自己的实际内容作为标识,从而使得只要是hibernate运行过得SQL语句均会被统计到。 结束语: Hibernate3提供这样一个功能,对于系统调优非常有帮助,在系统测试阶段,不用考虑由此统计工具带来的性能问题,可以详尽了解SQL语句的运行情况,从而视情况做优化。正式系统中不建议使用,因为统计本身会消耗较大的内存,如果短间隔的clear统计信息,得到的数据又没有说服力。 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |



