Ich habe die folgende select-Anweisung (mit sqlite3 und dem pysqlite Modul):Ist der unterbrechungsfreie Schlaf der Grund für mein Python-Programm wirklich langsam (und wenn ja, wie kann ich das lösen?)?
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)
die 55 Sekunden in Anspruch nimmt, wenn in Python läuft. Wenn es direkt in der SQLite-Befehlszeile ausgeführt wird, dauert es nur 15 ms. Jetzt ist mir aufgefallen, dass das Python-Programm in diesem Schritt in den ununterbrochenen Ruhezustand geht (31283 ndeklein 18 0 126m 24m 3192 D 1.0 0.0 2:02.50 python
, Das D in der obersten Ausgabe) und von 100% CPU auf etwa 1% CPU sinkt. Jetzt, da ich es während dieser Abfrage bemerkt habe, habe ich mir auch die oberste Ausgabe angesehen, als ich die Abfrage über here ausgeführt habe. Während dieser Zeit zeigt top auch an, dass es in den ununterbrochenen Schlaf wechselt, obwohl es zwischen R und D hin- und herwechselt und sich nur auf etwa 50% verlangsamt (es schwankt abhängig davon, ob es im D- oder R-Status ist).
Also jetzt ich denke, dass das ist, was verlangsamt meine Abfrage (bitte korrigieren Sie mich, wenn ununterbrochener Schlaf hat nichts mit Programmen Geschwindigkeit zu tun). Wenn das stimmt, wie kann ich sicherstellen, dass ein Programm diesen Status nicht erreicht?
Update 1:
Der QUERY EXPLAIN PLAN Python zurückgegeben:
(0, 0, 1, u'SCAN TABLE spectrum (~50000 rows)')
Der QUERY EXPLAIN PLAN sqlite der Befehlszeile zurückgegeben werden:
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)
Die EXPLAIN mit Python zurückgegeben:
(0, u'Trace', 0, 0, 0, u'', u'00', None)
Die EXPLAIN mit SQLite zurückgegeben:
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|
Und iostat zurückgegeben:
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
ich die Datenbank MySQL migriert und hier die Abfrage nur dauert etwa 0,001 Sekunde, , obwohl ich für alle anderen Abfragen tun werde Tatsächlich ist es langsamer als sqlite (ich habe es für sqlite optimiert, also könnte das vielleicht überraschen).
Verwenden Sie die gleiche Version der SQLite-Bibliothek von Python und in der SQLite-Shell? Normalerweise ist die Python Pysqlite Version ziemlich alt. – schlenk
Ja ich benutze die gleiche Version. –
Können Sie überprüfen, ob die Analyse von 'EXPLAIN' für jede Abfrage die gleiche ist, die in Python und die im Befehlszeilentool? (Sie müssen wahrscheinlich ein paar benutzerdefinierte Python für dieses Debugging schreiben.) – ghoti