Sqlite数据库有两个表,每个表超过2800万行。这是架构:
CREATE TABLE MASTER (ID INTEGER PRIMARY KEY AUTOINCREMENT,PATH TEXT,FILE TEXT,FULLPATH TEXT,MODIFIED_TIME FLOAT);
CREATE TABLE INCREMENTAL (INC_ID INTEGER PRIMARY KEY AUTOINCREMENT,INC_PATH TEXT,INC_FILE TEXT,INC_FULLPATH TEXT,INC_MODIFIED_TIME FLOAT);
以下是来自MASTER的示例行:
ID PATH FILE FULLPATH MODIFIED_TIME
---------- --------------- ---------- ----------------------- -------------
1 e:\ae/BONDS/0/0 100.bin e:\ae/BONDS/0/0/100.bin 1213903192.5
这些表的数据大多相同,MASTER中的MODIFIED_TIME和INCREMENTAL中的INC_MODIFIED_TIME之间存在一些差异。
如果我在sqlite中执行以下查询,我会得到我期望的结果:
select ID from MASTER inner join INCREMENTAL on FULLPATH = INC_FULLPATH and MODIFIED_TIME != INC_MODIFIED_TIME;
该查询将暂停一分钟左右,返回多行,再次暂停,返回更多等等,并完成没有问题。花大约2分钟完全归还所有东西。
但是,如果我在Python中执行相同的查询:
changed_files = conn.execute("select ID from MASTER inner join INCREMENTAL on FULLPATH = INC_FULLPATH and MODIFIED_TIME != INC_MODIFIED_TIME;")
它永远不会回来 - 我可以让它运行24小时但仍然没有任何东西。 python32.exe进程没有开始消耗大量的CPU或内存 - 它保持相当静态。而且这个过程本身实际上似乎没有反应 - 但是,我不能让Ctrl-C中断,并且必须杀死进程以实际停止脚本。
我没有小型测试数据库的这些问题 - 一切都在Python中运行良好。
我意识到这是一个大量的数据,但是如果sqlite正在处理实际的查询,那么python应该不会窒息,是吗?我可以从python对这个数据库做其他大的查询。例如,这有效:
new_files = conn.execute("SELECT DISTINCT INC_FULLPATH, INC_PATH, INC_FILE from INCREMENTAL where INC_FULLPATH not in (SELECT DISTINCT FULLPATH from MASTER);")
有什么想法吗? sqlite返回数据之间的暂停是否导致Python出现问题?或者是最终从未发生的事情表明查询结果的结束(如果是,为什么它适用于小型数据库)?
感谢。这是我的第一篇stackoverflow帖子,我希望我遵循相应的礼仪。
答案 0 :(得分:1)
Python倾向于使用旧版本的SQLite库,尤其是Python 2.x,它不会更新。
但是,您的实际问题是查询速度很慢。
使用常用机制对其进行优化,例如在INC_FULLPATH
和INC_MODIFIED_TIME
上创建两列索引。