У меня есть приложение для мониторинга, которое контролирует вызовы, которые могут иметь подкачки. Поэтому, если я хочу прочитать данные мониторинга, я хочу получить список вызовов, включая подколле. Вызовы могут быть вложены неограниченно.Как оптимизировать sql для чтения нескольких деревьев?
-START OF EDIT
В моем текущем тестовом столе имеется около 7 миллионов записей. В продуктивном использовании это может быть удвоенный размер. Ожидаемые дети на корневую запись составляют от 0 до 15, в очень немногих случаях может быть около 50 детей. Уровень иерархии довольно низок, максимум составляет около 5 уровней.
Ниже приведен мой подход к чтению ограниченного количества этих записей с помощью моего datamodel. Если у вас есть предложения по улучшению datamodel или запроса, я хотел бы услышать от вас.
END OF EDIT--
В общем, все записи в форуме, которые я нашел, касаются оптимизации чтения из одного дерева вместо нескольких деревьев.
В настоящее время у меня есть только одна таблица, как это:
create TABLE montest2
(
rootId VARCHAR(45) NOT NULL,
messageId VARCHAR(45) NOT NULL,
requestMessageId VARCHAR(45),
sessionId VARCHAR(45),
PRIMARY KEY (messageID)
);
RootID одинакова для всех вызовов, принадлежащих к одному дереву. Если у sessionId есть значение, мы знаем, что это вызов верхнего уровня (root). MessageId уникален для каждого вызова. RequestMessageId будет содержать сообщение parentId родителя.
Теперь я хочу прочитать первые 5 корневых вызовов, включая их детей. Я могу сделать это, используя следующие операторы:
EDIT: Обратите внимание, что я сузил свою проблему по этому запросу. У меня было дополнительное предложение WHERE для чтения родителей, чтобы я мог выбирать разных родителей. Но мои тесты показали, что они не отвечают за проблемы с производительностью. (КОНЕЦ РЕДАКТИРОВАНИЯ).
Чтение родителей:
ВЫБРАТЬ am.messageId montest2 утра (am.sessionID IS NOT NULL) ПЕРВЫЕ 5 Строк ТОЛЬКО
Чтение детей:
ВЫБОР ac.messageId ОТ montest2 ac INNER JOIN (SELECT am.rootID FROM montest2 am ГДЕ (am.sessionID НЕ НЕВОЗМОЖНО) ТОЛЬКО FETCH ТОЛЬКО 5 ROWS) родители ON ac.rootID = родители.rootID WHERE (ac.sessionID IS NULL);
Я знаю, что второе утверждение не быстро для многих записей. Может ли кто-нибудь дать мне несколько советов, как оптимизировать этот запрос? Или что я должен изменить о своей датемодели?
PS: Я использую Derby в качестве базы данных, но он должен работать с любой базой данных - это просто означало бы изменение синтаксиса ограничения (выборки первых x строк).
Добавление индекса в 'rootId' должно уже сделать запрос быстрее. – sp00m
Хорошее предложение. Но у меня уже есть индекс, и он все еще слишком медленный - больше советов? – Mgmr
Ваша структура данных на самом деле не является деревом –