2010-06-28 23 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