c++ - Speeding up Oracle database interface in Qt (QOCI) -
i have project involves integrating oracle database qt desktop app. since qt has easy use interface database interaction, compiled qoci driver support oracle connections.
everything works fine, processing time queries incredibly slow. how can improve performance?
my code processing arbitrary query looks this:
qlist< qlist<qstring> > dbwrapper::executequery(qstring const& querystring) { qlist< qlist<qstring> > results; if (_db.isopen()) { qsqlquery qry(querystring); if(qry.exec()) { while(qry.next()) { qlist<qstring> row; results.append(row); for(int = 0; < qry.record().count(); ++i) { results.last().append(qry.value(i).tostring()); } } } else { qdebug() << querystring; qdebug() << "failure: cannot handle query."; qdebug() << " > " << qry.lasterror(); } } else { qdebug() << "error opening database = " << _db.lasterror(); } return results; }
there ressources describing same issue other dbms in qt. of them suggesting add qry.setforwardonly(true)
, qry.prepare(querystring);
query setup.
although, seems style reading qt documentation, barely got me improvement. debugging code ran speed tests, reducing measure run time of qsql stuff.
//... qsqlquery qry(querystring); qry.setforwardonly(true); qry.prepare(querystring); qelapsedtimer timer; timer.start(); if(qry.exec()) { qdebug() << "time execute query: " << timer.elapsed() << "ms"; timer.start(); while(qry.next()) { // don't here } qdebug() << "time iterate through query results: " << timer.elapsed() << "ms"; }
turns out, executing query done in less 50 ms while iterating on results took 3000 ms, 100 elements in result of select statement.
the solution hard find, seems straight forward. when setting database connection can define connection options specific type of dbms working with. oci defines oci_attr_prefetch_rows
, defaults 1. setting higher value rapidly increases iteration speed.
_db = qsqldatabase::adddatabase("qoci"); _db.sethostname(host); _db.setdatabasename(dbname); _db.setport(port); _db.setusername(user); _db.setpassword(pwd); _db.setconnectoptions("oci_attr_prefetch_rows=1000"); _db.open();
please, correct me if wrong, guessing each select query cache maximum amount of rows in underlying storage structure in qt. believe number equal value of oci_attr_prefetch_rows
. since qry.value(...)
points 1 row (qsqlrecord), assuming oci_attr_prefetch_rows = 1
mean on each qry.next()
database somehow queried again internally move cursor. totally destroy performance did me.
i hope post found desperate facing issue.
Comments
Post a Comment