remove - ¿Es el sueño ininterrumpible la causa de que mi programa Python sea realmente lento(y si es así, cómo puedo resolver esto?)
python html scraping (2)
Tengo la siguiente declaración de selección (usando sqlite3 y el módulo pysqlite):
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)
Que tarda 55 segundos cuando se ejecuta en Python. Cuando se ejecuta directamente en la línea de comandos de SQLite, solo toma 15 ms. Ahora, noté que cuando está en este paso, el programa Python entra en modo de suspensión ininterrumpida ( 31283 ndeklein 18 0 126m 24m 3192 D 1.0 0.0 2:02.50 python
, la D en la salida superior) y baja del 100% de la CPU a aproximadamente 1 % UPC. Ahora que lo noté durante esta consulta, también observé la salida superior cuando ejecuté la consulta que pregunté here . Durante este tiempo, top también muestra que entra en modo de suspensión ininterrumpida, aunque cambia entre R y D y solo se ralentiza hasta alrededor del 50% (fluctúa dependiendo de si está en estado D o R).
Así que ahora creo que esto es lo que hace que mi consulta sea más lenta (corríjame si el sueño ininterrumpido no tiene nada que ver con la velocidad de los programas). Si esto es cierto, ¿cómo puedo asegurarme de que un programa no entra en este estado?
Actualización 1:
El EXPLAIN QUERY PLAN usando Python devolvió:
(0, 0, 1, u''SCAN TABLE spectrum (~50000 rows)'')
El EXPLAIN QUERY PLAN usando la línea de comando de sqlite devolvió:
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)
El EXPLICACIÓN utilizando Python devolvió:
(0, u''Trace'', 0, 0, 0, u'''', u''00'', None)
El EXPLICACIÓN utilizando sqlite devolvió:
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|
Y iostat volvió:
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
Actualización 2
Migré la base de datos a MySQL y aquí la consulta solo toma alrededor de 0.001 segundo, aunque para todas las demás consultas, en realidad es más lenta que sqlite (optimicé para sqlite, por lo que esto podría o no ser sorprendente).
Como mencioné en una respuesta a una pregunta anterior que hizo , ¿probó el módulo sqlite? Desde el sitio web :
APSW es un contenedor de Python para el motor de base de datos relacional integrado SQLite. A diferencia de otros envoltorios, como pysqlite, se enfoca en ser una capa mínima sobre SQLite que intenta traducir la API completa de SQLite a Python. La documentación tiene una sección sobre las diferencias entre APSW y pysqlite.
Lo intenté yo mismo y parece reflejar mejor cómo se ejecutan las sentencias de SQL con el "real" Sqlite (es decir, el cliente o la biblioteca C).
Hay un problema de rendimiento con SQLite y Python. Lea este hilo para más información. Hay algunas sugerencias allí; inténtelas, podría funcionar, como agregar un índice a sus campos de unión o usar pysqlite.
http://www.mail-archive.com/[email protected]/msg253067.html