SQLite 闭包 table 实现的性能问题

Performance issue on SQLite closure table implementation

首先我要说的是,我对 SQL 和数据库系统还很陌生,所以请原谅我可能犯的任何新手错误。

我正在使用闭包 table 在 SQLite 数据库中插入分层数据。我正在为 SQLite 版本 3.26.0 使用 C# (.NET 4.6.1) 和 SQLite 预编译的 32 位 DLL (x86)。插入的分层数据包含~240000个元素,最大树深度不大于7.

我的分层元素 table 是:

CREATE TABLE element (elementId INTEGER PRIMARY KEY, parentId INTEGER, elementName TEXT, FOREIGN KEY (parentId) REFERENCES element(elementId));

我的闭包 table 定义为:

CREATE TABLE hierarchy (parentId INTEGER, childId INTEGER, depth INTEGER, FOREIGN KEY(parentId) REFERENCES element(elementId), FOREIGN KEY(childId) REFERENCES element(elementId));

使用经典堆栈插入元素,该堆栈从“根”元素开始,在处理内部事务期间使用以下方式将元素的成员添加到该元素:

INSERT INTO element VALUES (<ELEMENT_ID>, <PARENT_ID>'<ELEMENT_NAME');

我用“self”关系初始化闭包table,使用:

INSERT INTO hierarchy(parentId, childId, depth) VALUES (<ELEMENT_ID>, <ELEMENT_ID>, 0);

这些插入不会导致任何问题,只需几秒钟即可执行。

接下来,我使用相同的堆栈方法再次遍历所有元素以构建闭包 table(注意:我可能会在前面的说明的同时执行此操作,但我是在一个单独的循环来隔离性能问题)使用以下代码(在另一个事务中):

INSERT INTO hierarchy SELECT p.parentId, c.childId, p.depth+c.depth+1 FROM hierarchy p, hierarchy c WHERE p.childId=<PARENT_ID> AND c.parentId=<ELEMENT_ID>;

但是,此查询需要数小时,甚至数天才能执行。它的执行时间也越来越长。我知道它在闭包 table 中插入了很多元素(当前元素及其所有上升项之间的每个关系一个条目),但我想知道是否可以做些什么来提高这里的性能?

谢谢

您需要子键和父键的索引。还将所有内容包装在一个事务中。

更好的是,使用单个递归 CTE 生成闭包 table,类似

with recursive
closure as (
    select elementId, elementId as parentId, 0 as depth from element
    union all
    select closure.elementId, element.parentId, 1 + depth as depth
    from closure, element where closure.parentId = element.elementId
)
select * from closure

要实际创建 table,请使用类似 create table hierarchy as 的方法将上述结果放入 table。