Foreign-Key

查詢執行速度很快,但會保持表鎖定一段時間

  • July 10, 2014

執行以下查詢非常快(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).

引用自:https://dba.stackexchange.com/questions/70078