是不可中断的睡眠我的Python程序的原因是真的很慢(如果是这样,我该如何解决这个问题?)?

我有以下select语句(使用sqlite3和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) 

在Python中运行需要55秒。 直接在SQLite命令行上运行它只需要15ms。 现在,我注意到,在这个步骤中,Python程序进入了不间断的睡眠状态( 31283 ndeklein 18 0 126m 24m 3192 D 1.0 0.0 2:02.50 python ,顶级输出中的D),并从100%的CPU下降到1 % 中央处理器。 现在我在查询过程中注意到了,在运行查询时我也查看了顶部输出。 在这段时间内,top也显示它会进入不间断的睡眠状态,虽然它在R和D之间来回切换,只减慢到50%左右(根据D或R状态而变化)。

所以现在我认为这是减慢我的查询速度(请纠正我,如果不间断的睡眠与程序速度无关)。 如果这是真的,我怎样才能确保程序不会进入这种状态?


更新1:

使用Python的EXPLAIN QUERY PLAN返回:

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

EXPLAIN QUERY PLAN使用sqlite的命令行返回:

 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) 

使用Python的EXPLAIN返回:

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

EXPLAIN使用sqlite返回:

 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| 

而iostat回来了:

 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 

更新2

我将数据库迁移到MySQL,这里的查询只需要大约0.001秒,即使对于所有其他查询,我正在做的实际上比sqlite(我已经为sqlite优化,所以这可能会或可能不会令人惊讶)慢。

正如我在前面提到的问题的答案中提到的那样,你是否给了sqlite模块apsw一个尝试? 从网站 :

APSW是SQLite嵌入式关系数据库引擎的Python包装器。 与其他包装如pysqlite相比,它着重于作为SQLite的最小层,试图将完整的SQLite API转换为Python。 文档中有关于APSW和pysqlite的区别。

我自己试了一下,似乎确实反映了SQL语句是如何由“真正的”Sqlite(即客户端或C库)执行的。

SQLite和Python有一个性能问题。 阅读此主题了解更多信息。 这里有一些建议 – 尝试它们,可能会起作用 – 比如向连接字段添加索引或使用pysqlite。

http://www.mail-archive.com/python-list@python.org/msg253067.html