Форум: "Базы";
Текущий архив: 2006.01.29;
Скачать: [xml.tar.bz2];
ВнизПомогите оптимизировать запрос. Firebird Найти похожие ветки
← →
atruhin © (2005-12-01 12:44) [0]Есть три таблицы: список товаров, приходные накладные, детализация приходных накладных. Необходимо запросом получить цену на все товары, на определенную дату, т.е. последнее поступление до данной даты.
select t.id, t.name, p.prihoddate, pd.price
from tovar t, prihod p, prihoddtl pd
where t.id = pd.reftovar and
Pd.refprihod = p.id and
p.prihoddate =(select max(prihoddate)
from tovar, prihod, prihoddtl
where tovar.id = prihoddtl.reftovar and
prihoddtl.refprihod = prihod.id and
tovar.id = t.id and
prihoddate <= :date1)
Получается, что внутренний запрос, выполняется для каждой записи внешнего. Очень долго. Если написать процедуру, без внутреннего запроса, где получаем полное декартово произведение tovar и prihoddtl, отсортированное по ID и дате, пример:
10-колбаса-10.10.2005-120
10-колбаса-11.10.2005-125
11-сыр-10.11.2005-130
А в ней перебором оставляем только последнюю строку каждой позиции. Скорость приемлемая. Но желательно обойтись без процедуры, т.к. приложение работает с чужими базами. Кто что может посоветовать?
← →
ANB © (2005-12-01 12:52) [1]
> atruhin © (01.12.05 12:44)
Не совсем понятно, для чего во внутреннем запросе использовать связку из трех таблиц. Вроде и так данных из наружного должно хватит. А вообще лучше запихать этот запрос во from и сделать с ним связку.
← →
Johnmen © (2005-12-01 13:02) [2]Почему не
p.prihoddate =(select max(prihoddate) from prihod prihoddate <= :date1)
?
И ещё. Чувстуется, что нужна где-то группировка...
← →
atruhin © (2005-12-01 15:05) [3]>>from и сделать с ним связку
В том то и проблема, что Firebird не поддерживает select ... from (select)
>>внутреннем запросе использовать связку из трех таблиц
В этом вся и проблема. Т.е. идем по списку товаров, для каждого товара получаем список приходных в которых он есть, выбираем последнюю.
>>Чувстуется, что нужна где-то группировка
Часа два сидел, крутил. Не получается. t.id, t.name - по ним логично группировать, p.prihoddate, pd.price - а вот эти поля нужно взять из приходной с максимальной датой.
Вообще там запрос побольше будет, привел аналогию для примера.
Пробовал "танцевать" от объединения таблицы детализации с нужными полями заголовка приходной, но получается то-же самое только вид сбоку.
← →
Sergey13 © (2005-12-01 15:22) [4]Ничего тут вроде не надо группировать. Запрос вроде нормальный, за исключением того что в подзапросе TOVAR лишний. Достаточно ссылки из внешнего.
where prihoddtl.reftovar= t.id and
prihoddtl.refprihod = prihod.id and
prihoddate <= :date1)
>Получается, что внутренний запрос, выполняется для каждой записи внешнего
По логике так и должно быть вроде.
А долго, так товаров то сколько? Может несколько тысяч.
>Очень долго.
Скока? Индексы все нужные есть?
← →
atruhin © (2005-12-01 15:36) [5]>>в подзапросе TOVAR лишний
Спасибо! Так и есть. Сейчас попробую что изменится.
Индексы все есть. Товаров около 600. Ежедневно поступает 30-100, плюс расходные накладные в той же таблице. Отсеиваются по ключевому полю.
Долго это 2-3 мин(PIV-3000/512mb). Для простой аналитической таблицы, это долго. С процедурой по вышеописанному алгоритму менее 10 сек, но хочу найти вариант без процедуры.
← →
Sergey13 © (2005-12-01 15:51) [6]2[5] atruhin © (01.12.05 15:36)
План выполнения в ИБЭксперте посмотри - какие индексы работают.
>Товаров около 600. Ежедневно поступает 30-100
Ежедневная поставка по 30-100 позициям наверное? Или я не понял.
>Индексы все есть.
Не может быть. 8-)
Вот например на prihod по id+prihoddate (или наоборот по prihoddate+id) наверное не помешал бы (попробовать стОит ИМХО).
>Вообще там запрос побольше будет, привел аналогию для примера.
Может тормоза в отрезанной части. 8-)
← →
atruhin © (2005-12-01 16:11) [7]>>Ежедневная поставка по 30-100 позициям наверное?
Да. Естественно.
>>id+prihoddate (или наоборот по prihoddate+id) наверное не помешал бы
Да в этом и суть, что в БД не желательно лезть. Это стороннее лицензионное приложение. Возникнут проблемы поставщик скажет: сами все испортили, и докажи что не индюк. В таком варианте у меня хранимка неплохо работает.
Составных индексов нет, одиночные есть все.
Я задавая вопрос имел ввиду, может можно к выборке с другого бока подойти как нибудь? Ведь задача для отчетов по моему не редкая. Сделать срез цен на дату. План запроса сейчас привести не могу, запрос на работе.
← →
Виталий Панасенко (2005-12-01 17:33) [8]А если на два запроса ? Найти максимальную дату и ее передать в
> select t.id, t.name, p.prihoddate, pd.price
> from tovar t, prihod p, prihoddtl pd
> where t.id = pd.reftovar and
> Pd.refprihod = p.id and
> p.prihoddate =:max_date
← →
DSKalugin © (2005-12-01 18:01) [9]структуру всех таблиц с индексами и план выполения запроса В СТУДИЮ!
← →
atruhin © (2005-12-01 18:23) [10]>>А если на два запроса ? Найти максимальную дату и ее передать в
Дак для каждого товара дата может быть своя.
>>структуру всех таблиц с индексами и план выполения запроса В СТУДИЮ!
Завтра утром.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.01.29;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.056 c