Foreign-Key
查詢執行速度很快,但會保持表鎖定一段時間
執行以下查詢非常快(75ms),但是從最後一行刪除評論變得很慢(2.5s),並且時間隨著表中的行數呈指數增長。
它創建一個具有外鍵約束的表並插入 8000 個隨機值,外鍵始終為 NULL。
8000 行插入非常快,並且可以非常快速地查詢它們。
但是幾秒鐘內就不可能放下桌子。
PRAGMA foreign_keys = 0; DROP TABLE IF EXISTS Drawings; CREATE TABLE Drawings ( PartNumber TEXT, Description TEXT NOT NULL, ParentPartNumber TEXT, FOREIGN KEY ( ParentPartNumber ) REFERENCES Drawings ( PartNumber ) ); CREATE UNIQUE INDEX PartNumber_Idx ON Drawings ( PartNumber ); INSERT INTO Drawings ( PartNumber, Description ) WITH RECURSIVE cte(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cte LIMIT 8000) SELECT x, random() FROM cte; PRAGMA foreign_keys = 1; SELECT * FROM Drawings; --DROP TABLE IF EXISTS Drawings;
編輯
我剛剛發現在刪除表時禁用外鍵檢查會加快操作:
PRAGMA foreign_keys = 0; DROP TABLE IF EXISTS Drawings; PRAGMA foreign_keys = 1;
問題仍然懸而未決:為什麼在填充上面的表後不能立即刪除表(或執行我尚未確定的其他操作),但可以在將數據庫單獨放置幾秒鐘或禁用後完成外鍵檢查?
文件說:
子鍵列不需要索引,但它們幾乎總是有益的。每次應用程序從父表中刪除一行時,它都會執行
$$ some query $$. 如果此 SELECT 完全返回任何行,則 SQLite 得出結論,從父表中刪除該行將違反外鍵約束並返回錯誤。如果這些查詢不能使用索引,它們將被迫對整個子表進行線性掃描。在一個重要的數據庫中,這可能非常昂貴。 因此,在大多數實際系統中,應該在每個外鍵約束的子鍵列上創建索引。子鍵索引不必是(通常也不會是)唯一索引。
您應該在
Drawings(ParentPartNumber)
.