首先,我是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(甚至几天)来执行。它的执行时间也越来越长。我知道它会在闭包表中插入很多元素(当前元素与其所有上升元素之间的每个关系一个条目),但是我想知道是否可以采取任何措施来提高性能?
谢谢
答案 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
之类的东西将上述结果放入表中。