![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Можно ли уменьшить время выполнения запроса [D7, IB6.x]
abhtr © (2008-11-21 11:43:00)Существует таблица товаров Prdca и существует таблица продаж этого товара (с кодом из справочника Dsptch_Prdca_ID) с указанием количества (Dsptch_Plan) и даты продажи (Dsptch_Date). Надо выбрать товары с самой поздней датой продажи.
Сделал запрос:
SELECT Dsptch_Prdca_ID, Dsptch_PostOffice_ID, Dsptch_Plan,
Dsptch_MMYY, Dsptch_Date
FROM Dsptch D1, Prdca
WHERE Dsptch_Prdca_ID = Prdca_ID
and D1.Dsptch_Date = (select max(Dsptch_Date)
from Dsptch D2
where D2.Dsptch_Prdca_ID=D1.Dsptch_Prdca_ID)
AND DSPTCH_MMYY = '1008'
and Prdca_Pttrn = 'Вкл.'
ORDER BY Dsptch_Prdca_ID, Dsptch_PostOffice_ID
Без строчки с ORDER BY выполняется около 15 сек., а с ORDER BY выполняется почти 15 МИНУТ(!!!)
Можно ли как-нибудь оптимизировать запрос для уменьшения времени выполнения?
Виталий Панасенко(дом) (2008-11-22 15:19:00) [1]
> sniknik © (22.11.08 11:11) [29]
я просто привел макет. а вся тормознутось оригинального запроса - из-за подзапроса...это "больное" место у ФБ(IB)... в плане скорости. лучше переписать в конструкцию for select do... .а в 2,х уже спокойно можно выполнить
> sniknik © (21.11.08 13:50) [14]
sniknik (2008-11-22 11:11:00) [2]> либо перейди на ФБ 2,х
и проверь там возможность нормальных подзапросов, объединений с ними.
> Примерно так, но тут неправильно 100%..:-)
не знаю как синтаксис, но тут и по логике не то, тут выбираются все записи на одну максимальную дату. и вполне вероятно что это будет всего одна запись, либо все из одной накладной (например), смотря как там, при каких условиях, у него идет изменение этого поля индивидуально карточками товара либо накладными.
а по задаче, имхо, должны выбираться все товары с максимальной датой изменения каждого.
если не так, и нужно именно то, что ты написал, то легко просто выполнить 2 запроса подряд, первым получить дату, и передать ее во второй параметром, и ничего менять в смысле версии будет не надо.
Виталий Панасенко(дом) (2008-11-22 10:02:00) [3]а по теме: убери подзапрос. сделай либо ХП, либо перейди на ФБ 2,х, там можно выполнить блок. тогда запрос можно переделать так
execute block
as
declare variable d date;
begin
select max(Dsptch_Date)
from Dsptch D2
where D2.Dsptch_Prdca_ID=D1.Dsptch_Prdca_ID into :d;
SELECT Dsptch_Prdca_ID, Dsptch_PostOffice_ID, Dsptch_Plan,
Dsptch_MMYY, Dsptch_Date
FROM Dsptch D1, Prdca
WHERE Dsptch_Prdca_ID = Prdca_ID
and D1.Dsptch_Date = :d
AND DSPTCH_MMYY = '1008'
and Prdca_Pttrn = 'Вкл.'
ORDER BY Dsptch_Prdca_ID, Dsptch_PostOffice_ID;
suspend;
end;
Примерно так, но тут неправильно 100%..:-)
Виталий Панасенко(дом) (2008-11-22 09:47:00) [4]
> sniknik © (21.11.08 15:14) [21]
>
> > Увы, запрос не прошел. Курсор останавливается после join
> и пишет:
> тогда забудь.
>
> > ИБ и его клоны
> IB ладно, черт с ним, но вот клоны... например про Firebird
> 2, читал/говорили что уже почти всю функциональность mssql
> поддерживает, и + что то исконно свое.
в 2,5 встроили регулярные выражения. правда, она пока альфа(эта версия)
Loginov Dmitry (2008-11-22 00:24:00) [5]> Посоветуйте, пожалуйста, какой индекс тогда лучше сделать?
>
Как минимум на поля DSPTCH_PRDCA_ID, DSPTCH_DATE (это - обязательно!). По правилам разработки баз данных нужны первычные ключи DSPTCH_ID и PRDCA_ID.
Кстати, почему DSPTCH_PRDCA_ID - SMALLINT, а PRDCA_ID - INTEGER?
Anatoly Podgoretsky (2008-11-21 18:57:00) [6]Я выбираю СУБД не по номеру версии, а под задачу, подойдет ли, и при том по очень многим факторам. Иногда выбирать не приходится, когда покупная программа, от которой нельзя отказаться или альтернативы еще хуже.
sniknik (2008-11-21 16:49:00) [7]ждать это конечно ;(...
но вот тем кто начинает сейчас это повод хотя бы не использовать старые версии (если не говорить о переходе на что то иное ;), не представляю, как без них?
не умом конечно понимаю, можно сделать процедуру, в ней цикл по курсору, т.е. добиться того же самого другими методами, но... это уже будет не язык общения с субд, а какой то суррогат с подменой самых нужных слов чем то искусственным.
Anatoly Podgoretsky (2008-11-21 16:40:00) [8]> sniknik (21.11.2008 15:14:21) [21]
Врут, но бог с ними, а мне что надо было ждать более 10 лет?
Вроде только где то в 7 версии появились встроеные запросы? Я точно не помню.
FireBird хоть он и не применим в данном случае, тоже не сразу обзавелся встроеными запросами.
sniknik (2008-11-21 15:18:00) [9]> Но пример в начале этой ветке не является примером вложенных запросов?
это что то типа функции в виде запроса... т.е. это вызывается на каждую итерацию.
обработка идет построчно, а не блоком как с нормальным подзапросом.
sniknik (2008-11-21 15:14:00) [10]> Увы, запрос не прошел. Курсор останавливается после join и пишет:
тогда забудь.
> ИБ и его клоны
IB ладно, черт с ним, но вот клоны... например про Firebird 2, читал/говорили что уже почти всю функциональность mssql поддерживает, и + что то исконно свое.
abhtr (2008-11-21 15:10:00) [11]
> Anatoly Podgoretsky © (21.11.08 15:05) [19]
Извините, что вклиниваюсь... Но пример в начале этой ветке не является примером вложенных запросов? Он - то у меня работает, правда, медленно...
Anatoly Podgoretsky (2008-11-21 15:05:00) [12]> sniknik (21.11.2008 13:50:14) [14]
Кстати ты помнишь в ветке где категорически рекомендуют начинающим ИБ и его клоны, так вот отсутствие вложеных запросов одназначно закрыло мне путь к этой СУБД.
Anatoly Podgoretsky (2008-11-21 15:04:00) [13]> sniknik (21.11.2008 13:50:14) [14]
А ИБ6 поддерживает вложеные запросы.
abhtr (2008-11-21 14:54:00) [14]Dsptch_Prdca_ID - поле ссылки на таблицу справочника товара Prdca
Dsptch_PostOffice_ID - поле ссылки на таблицу справочника торговой точки. Она в результате запроса нужна для оценки реализации товара по точкам.
Dsptch_Plan - количество товара (план) для реализации в торговой точке.
Dsptch_MMYY - отчетный период (месяц+год) для реализации товара
Dsptch_Date - дата "внутри" отчетного периода, для которого заполняется количество реализованного товара
Prdca_ID - код товара из справочника товара Prdca
Prdca_Pttrn - поле из справочника товара Prdca, для отметки товара, по которым будет происходить выборка для отчета.
> sniknik © (21.11.08 13:50) [14]
Увы, запрос не прошел. Курсор останавливается после joinи пишет:
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 11, char 13.
select.
Сергей М. (2008-11-21 14:02:00) [15]А где описание и назначение каждого из полей ?
abhtr (2008-11-21 13:56:00) [16]Извините за задержку, поздравляли сотрудника с днем рождения :о)
Однако...
Структуру привожу из скрипта таблиц:
CREATE TABLE DSPTCH (
DSPTCH_ID INTEGER,
DSPTCH_PRDCA_ID SMALLINT,
DSPTCH_PRHSPRICE_ID INTEGER,
DSPTCH_PRHSINIT_ID INTEGER,
DSPTCH_PRHSNN_ID INTEGER,
DSPTCH_POSTOFFICE_ID SMALLINT,
DSPTCH_PLAN SMALLINT,
DSPTCH_NOTSENT SMALLINT,
DSPTCH_WRITOFF SMALLINT,
DSPTCH_WRITOFF_ACT INTEGER,
DSPTCH_MMYY VARCHAR(4),
DSPTCH_DATE TIMESTAMP,
DSPTCH_NOTE VARCHAR(15)
);
CREATE TABLE PRDCA (
PRDCA_ID INTEGER,
PRDCA_INDEX VARCHAR(5),
PRDCA_NAME VARCHAR(35),
PUBLICHOUSE_ID INTEGER,
PRDCA_PTTRN VARCHAR(6)
);
sniknik (2008-11-21 13:50:00) [17]а вот такого вида запрос в IB6.x(кстати ????) пройдет
SELECT D1.Dsptch_Prdca_ID, D1.Dsptch_PostOffice_ID, D1.Dsptch_Plan, D1.Dsptch_MMYY, D1.Dsptch_Date
FROM Dsptch D1
inner join (select Prdca_ID, max(Dsptch_Date)
from Dsptch
group by Prdca_ID
where DSPTCH_MMYY = '1008' and Prdca_Pttrn = 'Вкл.') D2
on D1.Prdca_ID=D2.Prdca_ID and D1.Dsptch_Date=D2.Dsptch_Date
ORDER BY D1.Dsptch_Prdca_ID, D1.Dsptch_PostOffice_ID
конечно неясна структура таблиц, т.что связи наверняка неправильные, и непонятно зачем "присобачивается" Prdca, поэтому ее игнорировал, но по смыслу, сам стиль, объединение с подзапросом пройдет?
(если пройдет, то все лучше/быстрее будет один вызов подзапроса чем на каждую интерацию)
Сергей М. (2008-11-21 12:46:00) [18]Приведи подробную структуру обеих таблиц с описанием назначения каждого из их полей ..
Правильный$Вася (2008-11-21 12:44:00) [19]индексы нужны нато, по каким полям сортировка + по каким полям соединение таблиц
abhtr (2008-11-21 12:38:00) [20]
> пока не будет нужных индексов.
Посоветуйте, пожалуйста, какой индекс тогда лучше сделать?
По Dsptch_Prdca_ID, или Dsptch_Prdca_ID + Dsptch_Date?
И как их тогда надо использовать в запросе?