如何计算 Hibernate 在一个 Grails 请求中执行了多少 SQL 查询?

Posted

技术标签:

【中文标题】如何计算 Hibernate 在一个 Grails 请求中执行了多少 SQL 查询?【英文标题】:How can I count how many SQL queries hibernate does in one Grails request? 【发布时间】:2012-09-25 07:57:17 【问题描述】:

我需要用一个非常慢的请求来调试 Grails 应用程序。我有 SQL 日志记录,但希望在不手动计算的情况下查看 SQL 查询的数量。

debug    'org.hibernate.SQL'
trace    'org.hibernate.type'

例如,在每个请求之后都有以下行(其中 x 是对 SQL 服务器进行的所有查询的数量):

[2012-10-04 13:41:45,049][LoggingFilters] INFO - 请求在 8296 毫秒内完成并生成了 x 个 SQL 语句

经过一番谷歌搜索后,Grails 似乎无法做到这一点,所以也许 mysql 可以提供信息?

【问题讨论】:

看看这篇 this 博文。在这里你可以找到一个很好的解释如何测试对数据库的查询数。 【参考方案1】:

您可以通过使用过滤器和休眠统计信息来做到这一点。 在 conf 文件夹中创建类 ExampleFilters.groovy。这是课程的内容:

import org.hibernate.stat.Statistics
class ExampleFilters 

    def sessionFactory


    def filters = 
    // your filters here

        logHibernateStats(controller: '*', action: '*') 
            before = 
            Statistics stats = sessionFactory.statistics;
            if(!stats.statisticsEnabled) stats.setStatisticsEnabled(true)
                   

        afterView = 
            Statistics stats = sessionFactory.getStatistics()
            double queryCacheHitCount  = stats.getQueryCacheHitCount();
            double queryCacheMissCount = stats.getQueryCacheMissCount();
            double queryCacheHitRatio = (queryCacheHitCount / ((queryCacheHitCount + queryCacheMissCount) ?: 1))
            println """
######################## Hibernate Stats ##############################################
Transaction Count:$stats.transactionCount
Flush Count:$stats.flushCount
Total Collections Fetched:$stats.collectionFetchCount
Total Collections Loaded:$stats.collectionLoadCount
Total Entities Fetched:$stats.entityFetchCount
Total Entities Loaded:$stats.entityFetchCount
Total Queries:$stats.queryExecutionCount
queryCacheHitCount:$queryCacheHitCount
queryCacheMissCount:$queryCacheMissCount
queryCacheHitRatio:$queryCacheHitRatio
######################## Hibernate Stats ##############################################
"""
            stats.clear()
        

    

    


要阅读有关各种 Hibernate 统计信息的更多信息,请阅读这篇文章: http://www.javalobby.org/java/forums/t19807.html

还要注意,使用它时会对性能产生影响,所以它应该只在开发环境中使用。

【讨论】:

谢谢!这正是我正在寻找的资源! Hibernate API 文档中的Statistics 似乎也是一个查看的好地方。 嘿,我把它变成了Grails plugin,以防万一!还要感谢 Himanshu Seth 的 original post。【参考方案2】:

您是否考虑过一些技术含量较低的解决方案,例如通过 wc -l 运行输出?

【讨论】:

不幸的是,hibernate 不会在日志中每行打印查询。但是您可以计算字符串“select”的出现次数。当然,您必须在每个会话之间截断日志文件。但可以作为一种解决方法!【参考方案3】:

在 grails 中使用 loggingSql

dataSource 
 dbCreate = "update" // one of 'create', 'create-drop','update'
 url = "jdbc:postgresql://localhost:5432/demodb"
 loggingSql = true

您会注意到 Grails 使用的所有 SQL 语句都将被记录。

【讨论】:

是的,我已经启用了 loggingSql。我需要的是最后的 SQL 语句数。【参考方案4】:

正如 Burt Beckwith 在他的博文“我学到的咨询”http://burtbeckwith.com/blog/?p=1570987654321@中所说的那样

SQL 日志记录

有两种方法可以查看查询的 SQL 输出;在 DataSource.groovy 中添加 logSql = true 并配置 Log4j 记录器。 Log4j 方法要灵活得多,因为它不仅可以转储到标准输出,而且可以路由到文件或其他附加程序,并且可以方便地启用和禁用。但事实证明,切换 logSql SQL 控制台日志记录很容易。获取对 sessionFactory bean 的引用(例如,使用 def sessionFactory 的依赖注入)并使用

打开它
sessionFactory.settings.sqlStatementLogger.logToStdout = true

and off with

sessionFactory.settings.sqlStatementLogger.logToStdout = false

【讨论】:

谢谢。我已经设置了 Log4j,但如果没有它,这将是获取一些调试信息的更快方法。谢谢。

以上是关于如何计算 Hibernate 在一个 Grails 请求中执行了多少 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 grails 应用程序中监控 Hibernate 统计信息(缓存命中和未命中)?

如何使用hibernate grails 3,mysql?

grails 3(spring-boot) - 如何配置hibernate二级缓存

getGeneratedKeys() 上的 Grails Hibernate4 升级错误

Grails/Hibernate:版本控制上的空指针异常

Grails/Hibernate 数据库在负载下崩溃:无法连接(即使在池中)