Вначале я говорю, что я довольно плохо знаком с SQL и системами баз данных, поэтому, пожалуйста, извините меня за любые возможные ошибки, которые я могу совершить.
Я использую таблицу закрытия для вставки иерархических данных в базу данных SQLite. Я использую C # (.NET 4.6.1) и предварительно скомпилированную 32-разрядную DLL-библиотеку SQLite (x86) для SQLite версии 3.26.0. Вставленные иерархические данные содержат ~ 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));
Элементы вставляются с использованием классического стека, который начинается с «корневого» элемента, к которому добавляются члены элемента во время обработки внутри транзакции с использованием:
INSERT INTO element VALUES (<ELEMENT_ID>, <PARENT_ID>'<ELEMENT_NAME');
И я инициализирую таблицу закрытия с отношением «self», используя:
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>;
Однако выполнение этого запроса занимает ЧАСЫ, а может и дни. Время выполнения также становится все длиннее. Я знаю, что он вставляет много элементов в таблицу замыканий (по одной записи на отношение между текущим элементом и всеми его потомками), но я хотел бы знать, можно ли что-нибудь сделать, чтобы улучшить производительность здесь?
Спасибо