在进行SQL优化时,很重要的一点就是要看到底层执行的具体SQL,虽然可以通过打印日志的方式获取具体的SQL和SQL的执行效率,但是这样做很不方便,尤其在是使用Hibernate作为持久层时,大量的占位符让人很是头痛
P6Spy
P6Spy是一款开源的SQL监控工具,可以记录所有数据库操作及其消耗的时间
下载地址:http://sourceforge.net/projects/p6spy/files/p6spy/
使用起来非常简单(以下配置只适用于单独使用Hibernate的,对于Hibernate+Spring的项目不适用):
1,将p6spy.jar加入项目工程classpath中
2,将p6spy配置文件spy.properties加入项目工程/src目录下
3,将项目工程的数据库驱动修改为P6Spy提供的驱动(修改Hibernate配置文件hibernate.cfg.xml):
com.p6spy.engine.spy.P6SpyDriver
4,修改p6spy配置文件:
realdriver项修改为项目工程实际使用的驱动
# oracle driver
# realdriver=oracle.jdbc.driver.OracleDriver
# mysql Connector/J driver
# realdriver=com.mysql.jdbc.Driver
# informix driver
# realdriver=com.informix.jdbc.IfxDriver
# ibm db2 driver
# realdriver=COM.ibm.db2.jdbc.net.DB2Driver
# the mysql open source driver
#realdriver=org.gjt.mm.mysql.Driver
realdriver=com.mysql.jdbc.Driver
deregisterdrivers项一定要修改为true,原因注释已经说的很清楚了
#the DriverManager class sequentially tries every driver that is
#it's possible to registered to find the right driver.In some instances,
#load up the realdriver before the p6spy driver, in which case
#your connections will not get wrapped as the realdriver will "steal"
#the connection before p6spy sees it. Set the following property to "true"
#to cause p6spy to explicitily deregister the realdrivers
deregisterdrivers=true
修改P6Spy的日志记录方式,可选择根据Log4j配置控制日志输出(Log4jLogger)、控制台输出日志信息(StdoutLogger)、文件记录日志信息(FileLogger),示例中将日志信息输出到了日志文件中:
#specifies the appender to use for logging
#appender=com.p6spy.engine.logging.appender.Log4jLogger
#appender=com.p6spy.engine.logging.appender.StdoutLogger
appender=com.p6spy.engine.logging.appender.FileLogger
#name of logfile to use, note Windows users should make sure
#to use forward slashes in their pathname (e:/test/spy.log)
#(used for file logger only)
logfile=./log/spy.log
# append to the p6spy log file. if this is set to false the
# log file is truncated every time. (file logger only)
append=true
#The following are for log4j logging only
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=p6spy - %m%n
#log4j.appender.CHAINSAW_CLIENT=org.apache.log4j.net.SocketAppender
#log4j.appender.CHAINSAW_CLIENT.RemoteHost=localhost
#log4j.appender.CHAINSAW_CLIENT.Port=4445
#log4j.appender.CHAINSAW_CLIENT.LocationInfo=true
log4j.logger.p6spy=INFO,STDOUT
日志文件spy.log中记录的信息如下(第一个“|”右边的数字是SQL消耗的时间,单位为ms):
1399255288210|4|0|statement|select user0_.id as id0_, user0_.name as name0_, user0_.age as age0_ from
TEST_USER user0_ where user0_.id>2|select user0_.id as id0_, user0_.name as name0_, user0_.age as age0_ from
TEST_USER user0_ where user0_.id>2
1399255288217|-1||resultset|select user0_.id as id0_, user0_.name as name0_, user0_.age as age0_ from
TEST_USER user0_ where user0_.id>2|age0_ = 30, id0_ = 3, name0_ = ll
事实上,单独使用Hibernate的项目很少,大多数项目会同时使用Hibernate和Spring,此时数据库连接通常由Spring管理
无论是何种架构方式,只要保证在进行数据库操作之前,调用P6Spy的相关类,就可以让P6Spy监控到所有数据库操作并进行记录
所以本质上要做就是在每次数据库操作之前增加对P6Spy的调用:
1,将p6spy.jar加入Web工程WebRoot/WEB_INF/lib目录下
2,将p6spy配置文件spy.properties加入Web工程/src目录下
3,spy.properties的修改方式同上
4,修改Spring配置文件applicationContext.xml,对数据库连接进行封装(这里Spring通过JNDI查找数据源):
java:/comp/env/DB
classpath:hibernate.cfg.xml
Tomcat中数据源配置:
SQL Profiler
SQL Profiler是一款基于P6Spy的图形化监控工具,不但能够监控SQL执行,统计SQL的执行结果,还能根据SQL的执行效能提供优化建议,比起P6Spy的日志信息更加直观好用
下载地址:http://sourceforge.net/projects/sqlprofiler/files/sqlprofiler/
使用SQLProfiler自带的spy.properties文件覆盖上面的spy.properties文件,spy.properties文件中的realdriver项修改为项目工程实际使用的驱动,deregisterdrivers项修改为true
SQLProfiler要求P6Spy使用Log4j下的SocketAppender方式记录日志:
#specifies the appender to use for logging
appender=com.p6spy.engine.logging.appender.Log4jLogger
#appender=com.p6spy.engine.logging.appender.StdoutLogger
#appender=com.p6spy.engine.logging.appender.FileLogger
#The following are for log4j logging only
#log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
#log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
#log4j.appender.STDOUT.layout.ConversionPattern=p6spy - %m%n
log4j.appender.SQLPROFILER_CLIENT=org.apache.log4j.net.SocketAppender
log4j.appender.SQLPROFILER_CLIENT.RemoteHost=localhost
log4j.appender.SQLPROFILER_CLIENT.Port=4445
log4j.appender.SQLPROFILER_CLIENT.LocationInfo=true
#log4j.logger.p6spy=INFO,STDOUT
log4j.logger.p6spy=DEBUG, SQLPROFILER_CLIENT
将sqlprofiler.jar放至e盘下,打开cmd运行java -Xms200m -Xmx512m -jar sqlprofiler.jar即可弹出图形化监控界面
特别需要注意的是要先运行SQL Profiler,再运行需要进行监控的应用程序
Profile标签页包含所有P6Spy日志的详细信息和对每条日志信息的分析结果
Logger标签页中包含所有P6Spy记录的日志,并且可以根据日志级别,线程名等条件过滤出特定的日志条目
Analysis标签页则是图形化的分析结果
IronTrack SQL
SQL Profiler虽好用,但却是被动连接的,即SQL Profiler监测不到在其启动前启动的应用程序,并且如果SQL Profiler意外关闭,再次启动后必须重启其监控的应用程序,这一点不是很方便,在这一点上,IronTrack SQL就要好很多,IronTrack SQL是主动去监控应用程序的
1,使用IronTrack SQL自带的spy.properties文件覆盖上面的spy.properties文件,spy.properties文件中的realdriver项修改为项目工程实际使用的驱动,deregisterdrivers项修改为true,monitorport项为监控端口,默认值是2000
2,将irontracksql.jar加入项目工程classpath中/将irontracksql.jar加入Web工程WebRoot/WEB_INF/lib目录下(不需要添加其依赖包)
3,双击irontracksql.jar即可打开监控页面
点击Config按钮,在弹出的Configuration框中输入连接信息,输入完成后点击OK按钮,最后点击Connect按钮即可开始监控
更加详细的介绍,参见:http://www.ibm.com/developerworks/cn/java/j-lo-p6spy/