Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Новый топик    Ответить
 Оптимизация запроса.  [new]
Hisbreht Victor
Member

Откуда:
Сообщений: 107
Возникла следующая проблема. Может быть, она уже решалась на данном форуме, но пока не нашел ничего похожего.

Есть таблицы (менять структуру, скорее всего, нельзя,
но обоснованные советы по ее изменению тоже принимаются).
Таблицы достаточно большого объема.
Items - несколько тысяч записей,
Links - сотни тысяч записей, может быть, даже несколько миллионов.

Items (Id INT PRIMARY KEY, Name VARCHAR(64)) - справочник

Links (Id INT, PrevId INT) - ссылки на предков для организации дерева

DLinks (Id INT, PrevId INT) - ссылки на всех предков для ускорения
поиска по дереву

List (StrId, RDate DATE, ItemId, ...
FOREIGN KEY(ItemId) REFERENCES Items ON DELETE CASCADE)
- некая таблица со ссылками на Items

Требуется получить список элементов справочника с количеством записей в List,
ссылащихся на конкретный элемент и всех его потомков в дереве.

Сейчас это делается примерно так:

SELECT Id, PrevId, Name,
(
SELECT COUNT(DISTINCT StrId) FROM List
WHERE
ItemId=Items.Id OR
ItemId IN (SELECT Id FROM DLinks WHERE PrevId=Items.Id)
) AS Summ
FROM Items, Links WHERE Links.Id=Items.Id

Запрос выполняется непростительно долго. План доступа показывает, что
основные затраты (больше половины единиц времени) идут на поиск по DLinks.

Как можно перестроить запрос для существенного ускорения его выполнения?

Виктор
22 май 07, 21:04    [4171201]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
gardenman
Member

Откуда: С-Петербург
Сообщений: 2347
Ну так вы создайте план запроса, и положите здесь - посмотрим.
1) План запроса - смотрите по хелпу утилиты:
db2expln.exe
db2exfmt.exe

2) Создание таблиц объяснения: SQLLIB\MISC\explain.ddl
3) А также ничего не сказано какие есть индексы на других таблицах
4) Собиралась ли статистика?
23 май 07, 11:11    [4172941]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4949
Вы бы пример заполнения таблиц links и dlinks для 2-х предков одного item прислали.
И уточните задачу:
вы запрос делаете для конкретного item или для всего справочника items?
23 май 07, 11:16    [4172990]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
RomanSavelyev
Member

Откуда:
Сообщений: 90
А какие индексы имеются?
Стандартный совет - загнать запрос в Quest Central, запустить тюнер и прогнать через советчик по индексам (то же самое можно сделать из командной строк, но менее удобно)
23 май 07, 16:07    [4175739]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
Hisbreht Victor
Member

Откуда:
Сообщений: 107
Запрос делается по всему справочнику (запрос, кстати, приведен).
Индексы сделаны именно так, как рекомендовал советчик по индексам, хотя и до того при любой комбинации индексов картина была аналогичная, с точностью до небольшого ускорения или замедления, на общем фоне малозаметного. RUNSTAT и REORG выполнялись регулярно (реорганизовывалась вся БД), эффект опять совершенно незначительный.
В ближайшее время получить план доступа и заполнение таблиц не получится, не доберусь до компьютера с БД.
Могу пока только обрисовать на словах.
Согласно плану доступа (как я его запомнил) основное время тратится на индексскан по индексу таблицы DLinks, включающему оба поля таблицы.
У меня сложилось впечатление, что это все из-за того, что для каждого элемента справочника запрашиваются все его потомки. Ветвистость дерева преизрядная, глубина до 10 доходит.
Потому подумалось, что, может быть, можно построить рекурсивный запрос, обходящий дерево от листьев, и постепенно суммирующий результаты при движении к корню, чтобы постоянно эти листья не ворошить при подсчете в каждом узле. Или я что-то не совсем понимаю?
Если подсчитывать количество только для каждого узла дерева, без учета потомков, то все выполняется шустренько, но потомков надо учитывать полюбому. Уже подумываю о том, чтобы сначала получить сумму по каждому узлу, а потом в таблице-результате уже ручками дерево обойти от листьев до корня, и просуммировать.
23 май 07, 19:15    [4177025]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4949
И все-таки, скажите:
Если у вас
LINKS
------
ID PREVID
-- --
2 1
3 2

то в DLINKS будет

DLINKS
------
ID PREVID
-- --
2 1
3 2
3 1

или как?
23 май 07, 19:42    [4177087]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса.  [new]
gardenman
Member

Откуда: С-Петербург
Сообщений: 2347
Ну не знаю, я в любом бы случае написал рекурсивный запрос.- другой вариант - навесить триггер, который в случае добавления в дерево рекурсивно апдейтит некое поле у предков. Аналогично для удаления. Дле перемещения ветки - все также достаточно тривиально.
Тогда вам придется поднять только одну запись, чтобы получить ответ на ваш вопрос.
24 май 07, 11:09    [4179027]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить