0

我正在使用 AspecJ 来捕获每个表单中正在执行的查询,并显示每个查询执行所需的时间。我们正在使用spring jdbc,我的方面如下所示:@Aspect public class QueryProfilerAspect {

@Pointcut("call(* org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query*  (..))")
public void profileQuery() {
}

@Around("profileQuery()")
public Object profile(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    // System.out.println("Inside join point execution");
    SimpleJdbcTemplate template = (SimpleJdbcTemplate) thisJoinPoint
            .getTarget();
    JdbcTemplate jdbcTemplate = (JdbcTemplate) template
            .getNamedParameterJdbcOperations().getJdbcOperations();
    DataSource ds = jdbcTemplate.getDataSource();
    // System.out.println("Datasource name URL =="
    // + ds.getConnection().getMetaData().getURL());
    // System.out.println("Datasource name  ==" + schemaName);

    String sqlQuery = thisJoinPoint.getArgs()[0].toString();
    final long start, end;
    start = System.nanoTime();
    Object ll = thisJoinPoint.proceed();
    end = System.nanoTime();
    long executionTime = ((end - start) / 1000) / 1000;
    System.out.println("execution_time=" +executionTime  + sqlquery="+sqlQuery );
    return ll;

}

功能方面,这很有效,但是如果我把它放在我的应用程序中,它会使应用程序太慢。我正在使用编译时编织。方面在应用程序中找到了 1683 个 query* 方法调用。

我可以做些什么来优化它。任何建议/帮助将不胜感激。

4

1 回答 1

0

首先,我建议不要使用 System.nanoTime()。使用冷的精确度是残酷的,对于测量时间跨度几乎没有用处。如果您将结果除以,肯定不会比 System.currentTimeMillies() 好。

不过,最让你慢下来的可能是在你的方面的不同地方执行的字符串操作。如果必须连接字符串,至少在输出之前使用 StringBuilder 来完成。这可能已经由优化器完成,但你永远不能太确定。;)

而且...如果您想要进行日志记录,Sysout 并不完全是正确的方法 - 研究各种日志记录实现之一(带有 logback 的 slf4j 是我个人最喜欢的,但还有其他的)将值得您花时间。

特别是如果您想使用 Spring 具有您正在尝试构建的功能这一事实(如之前所问和回答的那样:在 Spring JdbcTemplate 中查看底层 SQL? (编辑:我知道这只是查询,而不是时间测量,但不必担心这一点也应该可以节省一些时间。)

于 2013-07-24T17:43:06.297 回答