Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
9-1123757977
TButton
2005-08-11 14:59
2006.01.29
GLScene


2-1136735763
АндрейЙ
2006-01-08 18:56
2006.01.29
Обращение к ячейкам DBGrid


2-1137256695
Silver__Dragon
2006-01-14 19:38
2006.01.29
вопрос по LISTBOX и OpenDialog


2-1136965083
BVV
2006-01-11 10:38
2006.01.29
КАк обработать html страницу?


3-1133077957
Lex_!
2005-11-27 10:52
2006.01.29
Работа с базой MSSQL через WEB





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский