我有一个代表的文件和目录层次结构的数据库表的大规模更新,具有以下结构(简化)的有效算法,它被设置为空目录。的为层次表
现在我需要为目录填充此列:它必须是所有后代(文件和目录)的最小BackupTime
。
这(幼稚和低效)查询说明了什么,我想做的事:
update Items i
set BackupTime = (select min(BackupTime)
from Items d
where d.Path like i.Path || '%'
and d.Type = 0)
where i.Type = 1
我的问题是,我似乎无法找到一个有效的方法。上面的查询时间太长对大量数据(此表通常包含超过10万行)
它可能会更快搜索仅在min(BackupTime)
直接孩子:
update Items i
set BackupTime = (select min(BackupTime)
from Items d
where d.ParentId = i.ItemId)
where i.Type = 1
但对于这为了工作,我必须确保后代会在他们的祖先之前更新,所以我必须从下往上递归地进行分级。问题是我没有简单的方法来知道哪些项目是最深层次的。我正在使用SQLite,所以我不能使用分层查询。
有关如何有效地做到这一点的任何想法?
理想情况下,我宁愿能做到在一个UPDATE查询,但如果这是不可能的,我开放给其他的选项,只要它们是有效的
谢谢,我会试一试! – 2012-04-26 22:47:32
好吧,花了5秒钟处理一个有100000个项目的数据库......这非常好;)。我尝试了一个“虚拟”数据库,所以我需要确定一个真实的数据库,但我相信它会有类似的性能。顺便说一下,'not exists'的最后一个条件是没有必要的:如果有null,'min'将返回null,所以它最终会得到相同的结果,迭代次数更少(14次而不是27次) – 2012-04-26 23:38:58
如果* only *值为NULL,MIN将返回NULL。如果NULL和其他值汇总,MIN不会返回NULL。 NOT EXISTS是需要保证迭代从下到上的。如果你删除NOT EXISTS,你会得到错误的结果!假设/ dir1 /包含两个项目 - 1)具有BackupTime 4/12的文件和2)包含具有备份时间4/9的1个文件的目录/ dir2 /。如果没有NOT EXISTS,在第一次迭代期间/ dir1 /将得到不正确的4/12的备份时间。不存在,它会等到下一次迭代。您看到的迭代次数越少,这些错误答案就越多。 – 2012-04-27 00:49:17