2012-03-29 70 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驅動程序的默認行爲。