我有一個代表的文件和目錄層次結構的數據庫表的大規模更新,具有以下結構(簡化)的有效算法,它被設置爲空目錄。的爲層次表
現在我需要爲目錄填充此列:它必須是所有後代(文件和目錄)的最小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