SQLite闭合表实现的性能问题

时间:2019-01-25 08:21:05

标签: performance sqlite hierarchical-data

首先,我是SQL和数据库系统的新手,所以请原谅我可能在做的任何noobie错误。

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

我的分层元素表是:

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

我的关闭表由以下内容定义:

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

使用经典堆栈插入元素,该堆栈以“ root”元素开头,在处理过程中,使用以下操作将元素的成员添加到其中:

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

然后我使用“自我”关系初始化闭包表:

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

这些插入没有问题,只需花费几秒钟即可执行。

接下来,我将使用相同的堆栈方法再次遍历所有元素以构建闭合表(注意:我可能可以在上一条指令的同一时间执行此操作,但是我在一个单独的循环中执行此操作以隔离性能问题),使用以下代码(在另一笔交易中):

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>;

但是,此查询需要HOURS(甚至几天)来执行。它的执行时间也越来越长。我知道它会在闭包表中插入很多元素(当前元素与其所有上升元素之间的每个关系一个条目),但是我想知道是否可以采取任何措施来提高性能?

谢谢

1 个答案:

答案 0 :(得分:0)

您需要有关子键和父键的索引。同时将所有内容包装在事务中。

更好的是,使用单个递归CTE生成闭合表,例如

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

要实际创建表,请使用create table hierarchy as之类的东西将上述结果放入表中。