我目前有一个闭包表,用于具有500万个节点的分层数据,这导致闭包表中约7500万行。使用SqLite,由于封闭表的大小,我的查询时间呈指数增长。关闭表根节点用10几百万个节点查询性能
CREATE TABLE `Closure` (`Ancestor` INTEGER NOT NULL ,`Descendant` INTEGER NOT NULL ,`Depth` INTEGER, PRIMARY KEY (`Ancestor`,`Descendant`))
CREATE INDEX `Closure_AncestorDescendant` ON `Closure` (`Ancestor` ASC, `Descendant` ASC);
CREATE INDEX `Closure_DescendantAncestor` ON `Closure` (`Descendant` ASC, `Ancestor` ASC);
CREATE TABLE `Nodes` (`Node` INTEGER PRIMARY KEY NOT NULL, `Root` BOOLEAN NOT NULL, `Descendants` INTEGER NOT NULL);
我查询发现,有根需要用这么多节点约20分钟,尽管只有约5或6个节点满足查询的节点。
SELECT `Closure`.`Ancestor` FROM `Closure`
LEFT OUTER JOIN `Closure` AS `Anc` ON `Anc`.`Descendant` = `Closure`.`Descendant`
AND `Anc`.`Ancestor` <> `Closure`.`Ancestor` WHERE `Anc`.`Ancestor` IS NULL;
20分钟至长,所以现在我存储用于如果该节点是一个根一个bool和修改Nodes
。 Root
列当节点被移动..我不完全满意重复数据,但我的查询时间现在在每个查询的单位数毫秒。
我还有很多查询需要知道给定节点有多少个后代(大多数情况下,如果后代> 1,以了解此对象是否可以在树视图中虚拟化/扩展)。我以前每次需要时都会询问这个问题,但是在一个巨大的数据库中,就像我甚至用索引查询似乎需要很长时间(超过1秒)一样,所以我也将它们减少到了Nodes
。 Descendants
列,我每次移动节点时也会更新。不幸的是,这是我想避免的另一个重复数据。
我以前使用的查询如下所示。如果任何人都可以解释如何提高性能(考虑到我已经有一个以祖先为起点的索引),我将不胜感激。
SELECT COUNT(*) FROM `Closure` WHERE `Ancestor`[email protected]
你的闭包表的模式是什么?有索引吗?另外,你是什么意思“找到根节点”? – 2012-01-20 21:36:31
对不起,这是一个错字。我的意思是“查找根源的节点”并且它已被更正。无论如何,我大多重写了我的问题,因为我们想出了如何正确编写索引,这些索引增加了除“Root”查询和“Count Descendants”查询之外的每个查询的性能。 – NtscCobalt 2012-01-21 07:01:57