2015-12-14 6 views
5

Sto supportando un'applicazione web Grails che mostra immagini diverse per client che utilizzano AmCharts. In una delle schede ci sono tre grafici, ognuno dei quali restituisce i primi dieci, quindi solo dieci righe, dal database basato su diverse misure. Ci vogliono 4-5 o talvolta anche più tempo per finire. La query viene eseguita sul DB in meno di 10 secondi.sql.rows() in Groovy sta funzionando lentamente

Il seguente metodo di servizio è chiamato a restituire i risultati:

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 

} 

Dopo alcune indagini era chiaro che la linea List rows = sql.rows(query, filterParams) è quella che riprende questo tempo di caricamento.

Qualcuno ha provato questo problema in precedenza? Perché sql.rows() impiega così tanto tempo quando restituisce solo 10 righe di risultati, e la query è runnig super veloce sul lato DB?

Ulteriori informazioni:

DB: FSL1D

il seguente comando sul lato DB: java -jar ojdbc5.jar - getversion restituisce: "Oracle 11.2.0.3.0 JDBC 3.0 compilato con JDK5 sul Thu_Jul_11_15: 41: Collegamento 55_PDT_2013 predefinito proprietà delle risorse mer 16 dicembre 08:18:32 EST 2015"

Groovy Versione: 2.3.7 Grails Versione: 2.4.41 JDK: 1.7.0

012.351.641,061 mila
+0

per consentire a più concreta risposta pls inviare un vostro DB, driver JDBC e la versione Groovy + JDK –

+0

DB: FSL1D il seguente comando sul lato DB: 'java-jar ojdbc5.jar - torna getversion': Oracle 11.2.0.3 .0 JDBC 3.0 compilato con JDK5 sul Thu_Jul_11_15: 41: 55_PDT_2013 #Default proprietà del collegamento delle risorse #Wed 16 dicembre 08:18:32 EST 2015 Groovy Versione: 2.3.7 Grails Versione: 2.4.41 JDK: 1.7.0 – krizsa

+0

grazie, proverò a impostare il tuo scenario. C'è una domanda simile [qui] (http://stackoverflow.com/questions/9923981/why-sql-rows-groovy-method-is-so-slow) ma non con una risposta definitiva. –

risposta

3

mio allestito con Groovy Version: 2.3.6 JVM: 1.8.0_11 e Oracle 12.1.0.2.0 utilizzando il driver ojdbc7.jar

nota l'attivazione del 10046 trace prima della corsa per permettere la diagnostica.

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}" 

L'esame della traccia mostra che lo stament viene analizzato ed eseguito, questo significa che se non v'è la clausola ORDER BY, tutti i dati vengono ordinati.

La dimensione di recupero viene utilizzato correttamente e non più di registrazioni richieste sono recuperati - qui 170 = 150 + 20. Con dimensioni di raccolta 100 questo avviene in due fasi (notare il parametro r - numero di righe recuperati).

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 

Quindi, in pratica l'unico problema che vedo che il "saltato" i dati vengono trasmessi attraverso la rete al client (per essere ignorato lì).

Questo potrebbe produrre un sovraccarico molto elevato di sovraccarico (e richiedere più tempo per la stessa query in esecuzione che produce in modo interattivo la prima pagina).

Ma il modo migliore per identificare il problema è semplice abilitare la traccia 10046 e vedere cosa succede. Sto usando il level 12 che significa che si ottengono anche le informazioni circa le attese nel DB e le variabili di binding.