2012-05-21 3 views
0

У меня есть приложение для мониторинга, которое контролирует вызовы, которые могут иметь подкачки. Поэтому, если я хочу прочитать данные мониторинга, я хочу получить список вызовов, включая подколле. Вызовы могут быть вложены неограниченно.Как оптимизировать 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 для чтения родителей, чтобы я мог выбирать разных родителей. Но мои тесты показали, что они не отвечают за проблемы с производительностью. (КОНЕЦ РЕДАКТИРОВАНИЯ).

  1. Чтение родителей:

    ВЫБРАТЬ am.messageId montest2 утра (am.sessionID IS NOT NULL) ПЕРВЫЕ 5 Строк ТОЛЬКО

  2. Чтение детей:

    ВЫБОР 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 строк).

+1

Добавление индекса в 'rootId' должно уже сделать запрос быстрее. – sp00m

+0

Хорошее предложение. Но у меня уже есть индекс, и он все еще слишком медленный - больше советов? – Mgmr

+0

Ваша структура данных на самом деле не является деревом –

ответ

1

я решил мою проблему сейчас следующим образом:

Я разделить мою одну таблицу со всеми записями в двух таблицах. Одна таблица содержит все корневые записи деревьев, другая содержит всех детей (и детей детей и т. Д.).
Итак, первый запрос выполняется против корневой таблицы, второй - против детей. Поскольку таблица с детьми составляет всего около четверти от размера, запрос быстрее.
Кроме того, я понял, что один из моих индексов был определен неправильно, чтобы он не вступил в действие. Я понял это объяснением, когда я попытался решить проблему в базе данных db2, используя инструменты db2.

Итак, мой совет для всех: Держите свои столы маленькими и используйте объяснения, чтобы узнать, делают ли вы индексы то, что они должны делать.

0

Почему бы не переместить соединение в предложение where, посмотрите, лучше ли это?

SELECT messageId 
FROM montest2 
WHERE rootID in (
     SELECT rootID from montest2 
     WHERE sessionID IS NOT null 
     FIRST 5 ROWS ONLY) AND 
     sessionID IS NOT null 
+0

Благодарим вас за это предложение. К сожалению, на самом деле это не влияет на производительность. С логической точки зрения ясно, что запрос становится все медленнее и медленнее, когда я увеличиваю предел в подзапросе. Но я не могу думать о лучшей идее ... – Mgmr

+0

Я отредактировал свой вопрос с цифрами и попытался объяснить, чего я хочу достичь. – Mgmr

Смежные вопросы