2012-06-01 11 views
16

Ho la seguente dichiarazione prescelta (utilizzando sqlite3 e il modulo pysqlite):È impossibile interrompere la causa del rallentamento del mio programma Python (e in tal caso, come posso risolverlo?)?

self.cursor.execute("SELECT precursor_id FROM MSMS_precursor "+ 
    "JOIN spectrum ON spectrum_id = spectrum_spectrum_id "+ 
    "WHERE spectrum_id = spectrum_spectrum_id "+ 
    "AND ROUND(ion_mz,9) = ? AND ROUND(scan_start_time,4) = ? "+ 
    "AND msrun_msrun_id = ?", select_inputValues) 

Quale prende 55 secondi durante l'esecuzione in Python. Quando viene eseguito direttamente sulla riga di comando di SQLite, richiede solo 15ms. Ora, ho notato che quando è in questa fase il programma Python entra in sospensione ininterrotta (31283 ndeklein 18 0 126m 24m 3192 D 1.0 0.0 2:02.50 python, The D in top output) e scende dal 100% della CPU a circa l'1% della CPU. Ora che l'ho notato durante questa query, ho anche guardato l'output più alto durante l'esecuzione della query che ho chiesto a here. Durante questo periodo top mostra anche che sta andando in sleep ininterrotto, sebbene passi avanti e indietro tra R e D e rallenti solo fino al 50% circa (oscilla a seconda che si trovi in ​​stato D o R).

Così ora io penso che questo è ciò che sta rallentando la mia interrogazione verso il basso (per favore correggetemi se sonno ininterrotto non ha nulla a che fare con la velocità dei programmi). Se questo è vero, come posso assicurarmi che un programma non entri in questo stato?


Update 1:

Il SPIEGARE piano di query utilizzando Python restituito:

(0, 0, 1, u'SCAN TABLE spectrum (~50000 rows)') 

Il SPIEGARE piano di query usando la linea di comando di SQLite restituito:

0|0|1|SCAN TABLE spectrum (~50000 rows) 
0|1|0|SEARCH TABLE MSMS_precursor USING INDEX fk_MSMS_precursor_spectrum_spectrum_id_1 (spectrum_spectrum_id=?) (~2 rows) 

Il SPIEGARE con Python restituito:

(0, u'Trace', 0, 0, 0, u'', u'00', None) 

Il SPIEGARE utilizza SQLite restituito:

0|Trace|0|0|0||00| 
1|Real|0|1|0|438.718658447|00| 
2|Real|0|2|0|692.6345000000001|00| 
3|Integer|1|3|0||00| 
4|Goto|0|39|0||00| 
5|OpenRead|1|33|0|13|00| 
6|OpenRead|0|39|0|5|00| 
7|OpenRead|2|41|0|keyinfo(1,BINARY)|00| 
8|Rewind|1|35|0||00| 
9|Column|1|8|5||00| 
10|RealAffinity|5|0|0||00| 
11|Integer|4|6|0||00| 
12|Function|2|5|4|round(2)|02| 
13|Ne|2|34|4||6a| 
14|Column|1|12|4||00| 
15|Ne|3|34|4|collseq(BINARY)|6c| 
16|Column|1|0|8||00| 
17|IsNull|8|34|0||00| 
18|Affinity|8|1|0|d|00| 
19|SeekGe|2|34|8|1|00| 
20|IdxGE|2|34|8|1|01| 
21|IdxRowid|2|7|0||00| 
22|Seek|0|7|0||00| 
23|Column|1|0|9||00| 
24|Column|2|0|10||00| 
25|Ne|10|33|9|collseq(BINARY)|6b| 
26|Column|0|1|5||00| 
27|RealAffinity|5|0|0||00| 
28|Integer|9|6|0||00| 
29|Function|2|5|11|round(2)|02| 
30|Ne|1|33|11||6a| 
31|Column|0|0|13||00| 
32|ResultRow|13|1|0||00| 
33|Next|2|20|0||00| 
34|Next|1|9|0||01| 
35|Close|1|0|0||00| 
36|Close|0|0|0||00| 
37|Close|2|0|0||00| 
38|Halt|0|0|0||00| 
39|Transaction|0|0|0||00| 
40|VerifyCookie|0|31|0||00| 
41|TableLock|0|33|0|spectrum|00| 
42|TableLock|0|39|0|MSMS_precursor|00| 
43|Goto|0|5|0||00| 

E iostat restituito:

io-bash-3.2$ iostat 
Linux 2.6.18-194.26.1.el5 (ningal.cluster.lifesci.ac.uk)   06/04/2012 

avg-cpu: %user %nice %system %iowait %steal %idle 
      14.35 0.00 0.30 0.01 0.00 85.34 

Device:   tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn 
sda    1.16   4.55  17.22 1520566 5752802 
sda1    0.00   0.02   0.00  5074   34 
sda2    1.16   4.53  17.22 1515184 5752768 
sdb    0.00   0.02   0.00  5108   0 
dm-0    2.29   3.88  16.70 1297226 5579336 
dm-1    0.00   0.00   0.00  928   0 
dm-2    0.11   0.65   0.52  216106  173432 

Update 2

ho migrato il database di MySQL e qui la query richiede solo circa 0,001 secondi, anche se per tutte le altre domande che faccio in realtà è più lento di sqlite (l'ho ottimizzato per sqlite, quindi potrebbe non essere sorprendente).

+1

Usi la stessa versione della libreria sqlite da python e nella shell sqlite? Di solito la versione di Python pysqlite è piuttosto antica. – schlenk

+0

Sì, io uso la stessa versione. –

+0

Puoi verificare che l'analisi da 'EXPLAIN' sia la stessa per ogni query, quella da Python e quella dallo strumento da riga di comando? (Probabilmente dovrai scrivere qualche Python personalizzato per questo debug.) – ghoti

risposta

0

C'è un problema di prestazioni con SQLite e Python. Leggi questa discussione per maggiori informazioni. Ci sono alcuni suggerimenti lì - provali, potrebbe funzionare - come aggiungere un indice ai tuoi campi di join o usare pysqlite.

http://www.mail-archive.com/[email protected]/msg253067.html

+1

Sto usando pysqlite e ho indici sul JOINS. Inoltre, funziona velocemente sia per MySQL tramite Python che per SQLite. –

+0

Hai un indice su spectrum_spectrum_id, ma non ne vedo uno su spectrum_id della tabella spettro. Il problema qui è specifico per Python + SQLite, quindi è OK che funzioni velocemente nella riga di comando di SQLite. Inoltre quale versione di pysqlite stai usando? – kjp

+0

Ho un indice su spectrum_id della tabella spettro. La mia versione di pysqlite è 2.6.3 –

2

come ho detto nel an answer to a prior question you asked, hai dato il modulo SQLite APSW una prova? From the website:

APSW è un wrapper Python per la SQLite database integrato relazionale motore. A differenza di altri wrapper come pysqlite, si concentra su come livello minimo su SQLite che tenta semplicemente di tradurre l'API SQLite completa in Python. La documentazione ha una sezione su le differenze tra APSW e pysqlite.

Ho provato da solo e sembra davvero riflettere meglio come le istruzioni SQL vengono eseguite dal Sqlite "reale" (vale a dire il client o la libreria C).

+0

Non l'ho provato, perché non riesco a scoprire come installarlo su una soluzione già esistente al posto di quella installata di default o usando -file per scaricarne uno nuovo –

+0

Che errore fai ottenere quando ne preleva uno nuovo? –

+0

Sono l'autore di APSW. Se si desidera utilizzare le librerie SQLite esistenti, lasciare semplicemente il parametro --fetch durante la creazione. Questo è documentato su http://apidoc.apsw.googlecode.com/hg/build.html#finding-sqlite-3 –

Problemi correlati