2012-03-29 93 views
4

我试图用sql.rows()Groovy方法获取一些数据,并且它花了很长时间才返回值。为什么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 
} 

回答

2

当你调用sql.rows,常规eventuallycallsSqlGroovyMethods.toRowResult由结果集返回的每一行。

此方法每次询问ResultSetMetaData的resultSet以查找列名称,然后从resultSet中将这些列中的每个列的数据提取到它添加到返回列表的Map中。

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

+0

感谢您的回应,但在我的测试中,我一次只能读取10行:所以SqlGroovyMethods.toRowResult只能调用10次。它无法解释性能差异。 – Yann 2012-03-29 12:00:54

+0

你有没有用'jvisualvm'来看看哪个函数花费时间? – 2012-03-29 12:14:01

2

我想我发现这个方法太慢的原因:statement.setMaxRows()永远不会被调用!

这意味着,大量的无用的数据是由数据库发送(如果你想看到一个大的数据网格的第一页)

+0

有趣...你可以在用户列表中提出这个问题,它可能值得作为一个错误提交,那里的人会比我更了解:-) – 2012-03-30 08:22:14

0

我不知道你的测试将如何了结,如果你用的setFetchSize,而不是尝试setMaxRows。这很多都是基于JDBC驱动程序的默认行为。