У меня есть таблица базы данных, которая представляет собой иерархию файлов и каталогов со следующей структурой (упрощенной):
ItemId int Path text Type int (0 for files, 1 for directories) ParentId int BackupTime datetime
В настоящее время столбец BackupTime
используется только для файлов, для каталогов он имеет значение null.
Теперь мне нужно заполнить этот столбец и для каталогов: это должно быть минимум 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
Моя проблема в том, что я не могу найти эффективный подход. Приведенный выше запрос выполняется слишком долго для больших объемов данных (эта таблица часто содержит более 100 000 строк).
Вероятно, было бы быстрее искать min(BackupTime)
только по прямым дочерним элементам:
update Items i
set BackupTime = (select min(BackupTime)
from Items d
where d.ParentId = i.ItemId)
where i.Type = 1
Но чтобы это работало, я должен гарантировать, что потомки будут обновляться раньше, чем их предки, поэтому я должен рекурсивно проходить иерархию снизу вверх. Проблема в том, что у меня нет простого способа узнать, какие элементы являются самыми глубокими в иерархии. Я использую SQLite, поэтому не могу использовать иерархические запросы.
Любая идея о том, как сделать это эффективно?
В идеале я бы предпочел сделать это в одном запросе UPDATE, но если это невозможно, я открыт для других вариантов, если они эффективны.