scraping remove parser htmlparser python linux performance sqlite sleep

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).