2015-12-14 33 views
5

我正在支持一個Grails Web應用程序,它爲使用AmCharts的客戶端顯示不同的視覺效果。在其中一個選項卡上有三個圖表,每個圖表根據不同的度量從數據庫中返回前十名,因此只有十行。需要4-5次或者更多的時間才能完成。查詢在10秒內在數據庫上運行。Groovy中的sql.rows()運行緩慢

以下服務方法被調用返回的結果:

List fetchTopPages(params, Map querySettings, String orderClause) { 
    if(!((params['country'] && params['country'].size() > 0) || (params['brand'] && params['brand'].size() > 0) || (params['url'] && params['url'].size() > 0))) { 
     throw new RuntimeException('Filters country or brand or url not selected.') 
    } 
    Sql sql = new Sql(dataSource) 
    sql.withStatement { stmt -> stmt.fetchSize = 100 } 
    Map filterParams = acquisitionService.getDateFilters(params, querySettings) 
    ParamUtils.addWhereArgs(params, filterParams) 
    String query = "This is where the query is" 

    ParamUtils.saveQueryInRequest(ParamUtils.prettyPrintQuery(query, filterParams)) 
    log.debug("engagement pageviews-by-source query: " + ParamUtils.prettyPrintQuery(query, filterParams)) 
    List rows = sql.rows(query, filterParams) 
    rows 

} 

經過一番調查,很明顯的是,List rows = sql.rows(query, filterParams)行是一個佔用了這個加載時間。

有沒有人以前曾經遇到過這個問題?爲什麼sql.rows()在只返回10行結果時花了這麼長時間,並且查詢在數據庫端的運行速度非常快?

附加信息:

DB:FSL1D以下對DB側命令

運行:java -jar ojdbc5.jar - getversion回報: 「甲骨文11.2.0.3.0 JDBC 3.0 JDK5編上Thu_Jul_11_15:41:55_PDT_2013 默認連接屬性資源 週三12月16日八時十八分32秒EST 2015"

Groovy的版本:2.3.7 Grails的版本:41年2月4日 JDK:1.7.0

+0

爲了讓更多的具體的答案請發表您的數據庫,JDBC驅動程序和Groovy + JDK版本 –

+0

DB:FSL1D 在DB側 運行以下命令:'Java的罐子ojdbc5.jar - getversion'回報: 的Oracle 11.2.0.3 .0 JDBC 3。0與JDK5上Thu_Jul_11_15編譯:41:55_PDT_2013 #默認連接屬性資源 #Wed年12月16八時18分32秒EST 2015 Groovy的版本:2.3.7 Grails的版本:41年2月4日 JDK:1.7.0 – krizsa

+0

謝謝,我會嘗試設置你的場景。有一個類似的問題[這裏](http://stackoverflow.com/questions/9923981/why-sql-rows-groovy-method-is-so-slow),但沒有一個明確的答案。 –

回答

3

我的設置Groovy Version: 2.3.6 JVM: 1.8.0_11Oracle 12.1.0.2.0使用驅動程序ojdbc7.jar

注意10046 trace激活運行前,允許診斷用。

import oracle.jdbc.pool.OracleDataSource 

def ods = new OracleDataSource(); 
ods.setURL('url') 
ods.setUser('usr') 
ods.setPassword('pwd') 

def con = ods.getConnection() 
def sql = new groovy.sql.Sql(con) 
sql.withStatement { stmt -> stmt.fetchSize = 100 } 
def SQL_QUERY = """select id, col1 from table1 order by id""" 
def offset = 150 
def maxRows = 20 
// activate trace 10046 
con.createStatement().execute "alter session set events '10046 trace name context forever, level 12'" 

def t = System.currentTimeMillis() 
def rows = sql.rows(SQL_QUERY, offset, maxRows) 
println "time1 : ${System.currentTimeMillis()-t} with offset ${offset} and maxRows ${maxRows}" 

跟蹤的檢查表明,stament分析和執行,這意味着如果有ORDER BY子句,所有的數據進行排序。

獲取大小被正確使用和不超過所需的記錄更被提取 - 在這裏170 = 150 + 20 隨着取這是在兩個步驟(注意r參數 - 數的讀取的行)進行大小100。

FETCH #627590664:c=0,e=155,p=0,cr=5,cu=0,mis=0,r=100,dep=0,og=1,plh=1169613780,tim=3898349818398 
FETCH #627590664:c=0,e=46,p=0,cr=0,cu=0,mis=0,r=70,dep=0,og=1,plh=1169613780,tim=3898349851458 

所以基本上唯一的問題我看到「跳過」的數據通過網絡傳遞到客戶端(並在那裏忽略不計)。

這可能具有非常高的偏差很大的開銷產生(以及相同的查詢運行交互地製作的第一頁需要更多的時間)。

但確定問題的最佳方法很簡單,就是啓用10046跟蹤並查看正在發生的事情。我使用的是 level 12,這意味着您還會獲得關於DB中的等待和綁定變量的信息 。