【问题标题】:Why sql.rows Groovy method is so slow为什么 sql.rows Groovy 方法这么慢
【发布时间】:2012-03-29 10:56:21
【问题描述】:

我尝试使用 sql.rows() Groovy 方法获取一些数据,但返回值需要很长时间。

所以我尝试了“标准”方式,它的速度要快得多(快 150 倍)。

我错过了什么?

看下面的代码:第一个方法在大约 2500 毫秒内返回结果,第二个在 15 毫秒内返回结果!

class MyService {

javax.sql.DataSource dataSource

def SQL_QUERY = "select M_FIRSTNAME as firstname, M_LASTNAME as lastname, M_NATIONALITY as country from CT_PLAYER order by M_ID asc";

def getPlayers1(int offset, int maxRows)
{
    def t = System.currentTimeMillis()
    def sql = new Sql(dataSource)
    def rows = sql.rows(SQL_QUERY, offset, maxRows)
    println "time1 : ${System.currentTimeMillis()-t}"
    return rows
}

def getPlayers2(int offset, int maxRows) 
{
    def t = System.currentTimeMillis();
    Connection connection = dataSource.getConnection();
    Statement statement = connection.createStatement();
    statement.setMaxRows(offset + maxRows -1);
    ResultSet resultSet = statement.executeQuery(SQL_QUERY);
    def l_list =[];
    if(resultSet.absolute(offset)) {
        while (true) {
            l_list << [
                'firstname':resultSet.getString('firstname'),
                'lastname' :resultSet.getString('lastname'),
                'country'  :resultSet.getString('country')
            ];
            if(!resultSet.next()) break;
        }
    }
    resultSet.close()
    statement.close()
    connection.close()
    println "time2 : ${System.currentTimeMillis()-t}"
    return l_list
}

【问题讨论】:

    标签: grails groovy


    【解决方案1】:

    当你调用 sql.rows 时,对于 resultSet 返回的每一行,groovy eventually calls SqlGroovyMethods.toRowResult

    此方法每次都会查询ResultSetMetaData 的resultSet 以查找列名,然后将这些列中每一列的数据从resultSet 中提取到一个Map 中,并将其添加到返回的List 中。

    在您的第二个示例中,您直接获取名称所需的列(因为您知道它们是什么),并且避免必须对每一行进行此查找。

    【讨论】:

    • 感谢您的回复,但在我的测试中,我一次只获取 10 行:所以 SqlGroovyMethods.toRowResult 只被调用了 10 次。它无法解释性能差异。
    • 你有没有用jvisualvm 看看哪个函数占用了时间?
    【解决方案2】:

    我想我找到了这个方法这么慢的原因:statement.setMaxRows() 永远不会被调用!

    这意味着数据库发送了大量无用的数据(当您想查看大型数据网格的第一页时)

    【讨论】:

    • 有趣...你能在用户列表上问这个吗,它可能值得作为一个错误提交,那里的人会比我更了解:-)
    【解决方案3】:

    我想知道如果您尝试使用 setFetchSize 而不是 setMaxRows,您的测试结果会如何。这很大程度上取决于底层 JDBC 驱动程序的默认行为。

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 2016-09-28
      相关资源
      最近更新 更多