[PyQt] Extracting QSqlQuery results in PyQt4

Aaron Digulla digulla at hepe.com
Wed Oct 8 21:20:20 BST 2008


mir amicitas schrieb:
> I am trying to use SQLite in a PyQt4 application. I am running into a
> problem where it is taking a really long time to get the data out of
> the QSqlQuery object after a query is completed. Here is a code
> snippet with the relevant parts:
> 
> #################################################################
>         self.selected_columns = self.table_definition['track']
>         select_string = ','.join(self.selected_columns)
> 
>         query_str = 'SELECT %s FROM track %s'%(select_string, where_string)
> 
>         start_time = time.clock()
>         self.query.prepare(query_str)
>         self.query.exec_()
>         util.message('Query took:', time.clock() - start_time, 'seconds')
> 
>         print ''
>         print query_str
> 
>         results = []
>         header = self.selected_columns
> 
>         self.query.first()
> 
>         while self.query.isValid():
>             record = [self.query.value(index).toString() for index in
> range(len(header))]
>             results.append(record)
>             self.query.next()
> 
>         util.message('Selected', len(results), 'records.')
> 
>         util.message('Unpacking Took:', time.clock() - start_time, 'seconds')
> 
> #################################################################
> 
> While the query is quick, extracting the data takes a really long
> time. Way longer than I think it should take.
> 
> Here are the results:
> #################################################################
> Query took: 0.00094797466213 seconds
> 
> SELECT artist,album,title,url,musicbrainz_trackid,hystrix_trackid FROM track
> Selected 16668 records.
> Unpacking Took: 5.29902267251 seconds
> #################################################################
> 
> #################################################################
> Query took: 0.0317866355896 seconds
> 
> SELECT artist,album,title,url,musicbrainz_trackid,hystrix_trackid FROM
> track WHERE (album LIKE '%it%' OR title LIKE '%it%' OR artist LIKE
> '%it%')
> Selected 3262 records.
> Unpacking Took: 1.4495204451 seconds
> #################################################################
> 
> I also to tried just cycling through the code instead of actually
> extracting the data:
> 
> #################################################################
> while self.query.next():
>         pass
> #################################################################
> 
> Results:
> #################################################################
> Query took: 0.171307952858 seconds
> 
> SELECT artist,album,title,url,musicbrainz_trackid,hystrix_trackid FROM track
> Selected 0 records.
> Unpacking Took: 1.24349849063 seconds
> #################################################################
> 
> This is certainly faster, but still this is a long time to just to
> cycle though the records.
> 
> If I use a simplified extraction:
> #################################################################
> while self.query.next():
>             record = [self.query.value(index) for index in range(len(header))]
>             results.append(record)
> #################################################################
> 
> Results:
> #################################################################
> Query took: 0.00130084772843 seconds
> 
> SELECT artist,album,title,url,musicbrainz_trackid,hystrix_trackid FROM track
> Selected 16667 records.
> Unpacking Took: 3.68243214225 seconds
> #################################################################
> 
> I also tried doing the loop (including string conversion) with out
> appending the results. That took 4.5 seconds.
> 
> What this means is that the time break down is:
> 1.2 seconds just to loop through the records.
> 1.7 seconds to extract the data from the records.
> 0.8 seconds to convert to a string.
> 0.7 seconds to create the python list.
> 
> While I probably can't reduce the time it takes to create the python
> list much, and I can avoid the string conversion, is there anyway to
> reduce the looping and extracting?
> 
> I have tried using setForwardOnly() but I did not notice a difference.
> 
> Does anyone have any idea on why this is taking so long or how I can
> improve things?

It seems that loading 10'000 records out of the sqlite DB just takes a
couple of seconds. sqlite isn't very fast when you have a lot of data
(and yeah, 10'000 isn't that much ...).

You must find a way to split the operation into smaller chunks. Also try
the python sqlite3 module to get a feeling if Python is slow or if it's
Qt or PyQt.

In my app, I'm running sqlite operations in a background thread so they
won't block the user from working. It takes a bit of effort but it was
much more simple than I expected.

Regards,

-- 
Aaron "Optimizer" Digulla a.k.a. Philmann Dark
"It's not the universe that's limited, it's our imagination.
Follow me and I'll show you something beyond the limits."
http://darkviews.blogspot.com/          http://www.pdark.de/


More information about the PyQt mailing list