2014-06-17 45 views
2

我在我的應用程序中使用SQLite數據庫來存儲測量數據。SQLite:ON DELETE CASCADE性能不佳

它在項目組中組織。這些表與外鍵互連,使用ON DELETE CASCADE來處理鏈接。該數據庫是這樣的:

  • 表項目
  • 表族(外鍵:PROJECT_ID)
  • 表文件(外鍵:GROUP_ID)
  • 表數據點(外鍵:FILE_ID)

所有外鍵參考列聲明像

project_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT

的外鍵聲明如下

FOREIGN KEY(project_id) REFERENCES Projects(project_id) ON DELETE CASCADE

現在我有1個項目,1組項目,800個文件,該組中,每個文件約60個數據點。

使用DELETE FROM Groups WHERE project_id=1刪除羣組效果很好,但需要大約21秒,這對我的需求來說太長了。

我在事務中包裝了刪除。

我是SQL和SQLite的極端新手。這個持續時間是否正常,或者有什麼方法可以加快速度?我需要刪除組以填寫更新後的值。在我的應用程序中,我只想將一個項目保留在內存中,因此只需刪除整個數據庫並從頭開始填充(儘管快得多,〜1 sek)並不是真正的選擇。

中的表創建這樣的:

'Create projects table 
cmd.CommandText = "CREATE TABLE IF NOT EXISTS Projects (ProjectID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " & _ 
     "name TEXT NOT NULL, comment TEXT, date DATETIME2, diameter FLOAT(53), thickness FLOAT(53));" 

'Create Groups table 
cmd.CommandText &= vbNewline & "CREATE TABLE IF NOT EXISTS Groups (GroupID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, project_id INTEGER NOT NULL, " & _ 
     "name TEXT NOT NULL, text TEXT NOT NULL, fixed TINYINT NOT NULL, " & _ 
     "FOREIGN KEY(project_id) REFERENCES Projects(ProjectID) ON DELETE CASCADE);" 
+1

貴公司的所有外鍵列有他們的索引?如果不是,添加一個索引應該加快刪除。 – GarethD

+0

對不起,但是你有什麼意思呢''有一個索引'?我會將表格聲明添加到我的問題中。 – Jens

回答

5

documentation說:

指數是不需要的子鍵列,但他們幾乎總是有益的。 [...]

每次應用程序從...父表中刪除一行時,它都會執行[查詢]來搜索...子表中的引用行。

如果此查詢完全返回任何行,則SQLite得出結論,從父表中刪除行將違反外鍵約束並返回錯誤。如果修改父鍵的內容或將新行插入到父表中,可能會運行類似的查詢。如果這些查詢不能使用索引,則他們被迫對整個子表進行線性掃描。在一個不平凡的數據庫中,這可能會非常昂貴。

因此,在大多數實際系統中,應該在每個外鍵約束的子鍵列上創建一個索引。子鍵索引不必是(通常不會是)UNIQUE索引。

所以,你應該對孩子鍵列創建索引:

CREATE INDEX Groups_project_id_index ON Groups(project_id); 
+0

Ahkay,我是在將數據添加到表格之前還是之後執行此操作?像我創建表並立即添加此索引? (我需要閱讀這個主題,因爲我之前沒有聽說過它:-)) – Jens

+0

我在表創建後立即添加它,現在它工作得更快。謝謝! – Jens