2010-06-28 55 views
4

我使用pythons内置的sqlite3模块来访问数据库。我的查询在包含150000个条目的表和40000个条目的表之间执行连接,结果再次包含约150000个条目。如果我在SQLite Manager执行查询需要几秒钟,但如果我从python执行相同的查询,它在一分钟后还没有完成。这里是我使用的代码:加入pythons sqlite模块比手动执行要慢

cursor = self._connection.cursor() 
annotationList = cursor.execute("SELECT PrimaryId, GOId " + 
           "FROM Proteins, Annotations " + 
           "WHERE Proteins.Id = Annotations.ProteinId") 
annotations = defaultdict(list) 
for protein, goterm in annotationList: 
    annotations[protein].append(goterm) 

我做了fetchall只是为了衡量执行时间。有没有人有解释性能的巨大差异?我在Mac OS X 10.6.4上使用Python 2.6.1。

编辑

我实现手动加入,这样更快。代码如下所示:

cursor = self._connection.cursor() 
proteinList = cursor.execute("SELECT Id, PrimaryId FROM Proteins ").fetchall() 
annotationList = cursor.execute("SELECT ProteinId, GOId FROM Annotations").fetchall() 
proteins = dict(proteinList) 
annotations = defaultdict(list) 
for protein, goterm in annotationList: 
    annotations[proteins[protein]].append(goterm) 

因此,当我自己提取表,然后在python中执行连接时,大约需要2秒。上面的代码需要永远。我在这里错过了什么吗?

第二编辑 我试图用同样现在apsw,它工作得很好(代码并不需要在所有改变),性能也不错。我仍然想知道为什么sqlite3-模块这么慢。

回答

5

有一个关于在这里讨论:http://www.mail-archive.com/[email protected]/msg253067.html

似乎存在sqlite3的模块中的性能瓶颈。有一个advice如何让你的查询速度更快:

  • 确保您有连接列上的索引
  • 使用pysqlite
+0

SQLite的指标,我使用Python 2.6.5。它在PySqlite主页上说,Python自带的'sqlite3'包与'PySqlite'相同,但它没有说明哪个版本。 – 2010-09-15 12:01:13

+0

尝试获得较新版本 – tamasd 2010-09-15 12:49:12

1

您还没有发布的表的架构问题,但我认为索引可能存在问题,特别是没有关于Proteins.Id或Annotations.ProteinId(或两者)的索引。

像这样创建

CREATE INDEX IF NOT EXISTS index_Proteins_Id ON Proteins (Id) 
CREATE INDEX IF NOT EXISTS index_Annotations_ProteinId ON Annotations (ProteinId) 
+1

该ID被创建为'INTEGER PRIMARY KEYS',意味着默认情况下它们上有索引。当我使用'apsw'而不是Pythons'sqlite3'模块时,相同的模式会产生更好的性能,所以我怀疑模式是否是问题。 – 2010-09-17 13:52:21