Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Можно ли уменьшить время выполнения запроса [D7, IB6.x]


Страницы:   1 2

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?
И как их тогда надо использовать в запросе?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо