-
Существует таблица товаров 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 МИНУТ(!!!) Можно ли как-нибудь оптимизировать запрос для уменьшения времени выполнения?
-
Приведи детальный план запроса
-
План PLAN (D2 NATURAL) PLAN JOIN (D1 NATURAL,PRDCA INDEX (RDB$PRIMARY3))
Адаптированный план PLAN (D2 NATURAL) PLAN JOIN (D1 NATURAL,PRDCA INDEX (PK_PRDCA))
------ Performance info ------ Prepare time = 0ms Execute time = 14s 875ms Avg fetch time = 619.79 ms Current memory = 5 664 764 Max memory = 5 803 809 Memory buffers = 1 262 Reads from disk to cache = 0 Writes from cache to disk = 0 Fetches from cache = 18 534 461
Я правильно понял?
-
Еще приведи статистику использования индексов при выполнении запроса
-
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 D1.Dsptch_Date = (select max(Dsptch_Date) from Dsptch D2 where D2.Dsptch_Prdca_ID=D1.Dsptch_Prdca_ID AND DSPTCH_MMYY = '1008')
будет не правильнее?
-
Таблицы у меня без индексов. Работаю на IB Expert. Нашел еще вот это: Query ------------------------------------------------ /* Текст запроса для формирования новой разнарядки по НОВОМУ алгоритму.
Из справочника изданий нужно выбрать издания отмеченные как "ВКЛ." Для этих изданий надо выбрать записи из разнарядки за прошлый заданный период DSPTCH_MMYY с последней датой формирования Dsptch_Date и переписать значение Dsptch_Plan */
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 14мин 49 сек.*/ /* ORDER BY Dsptch_Prdca_ID, Dsptch_Date, Dsptch_PostOffice_ID 14мин 42 сек.*/
/*Текст запроса для РАЗНАРЯДКИ (и для TfrmWork.dbgWorkTitleClick разнарядки)*/ /* SELECT Prdca_Index, Prdca_Name, PostOffice_Name, PostOffice_Tract, PrHsNN_Quantity, Dsptch_Plan*PrHsNN_Quantity PlQn, PrHsInit_Initial, PrHsPrice_SumPblcHs, PrHsPrice_RetaPrc, Dsptch_ID, Dsptch_Prdca_ID, Dsptch_PostOffice_ID, Dsptch_Plan, Dsptch_PrHsInit_ID, Dsptch_PrHsPrice_ID, Dsptch_NotSent, Dsptch_WritOff_Act, Dsptch_MMYY, Dsptch_Date, Dsptch_Note FROM Dsptch, Prdca, PostOffice, PrHsPrice, PrHsInit, PrHsNN WHERE Dsptch_Prdca_ID = Prdca_ID AND Dsptch_PrHsPrice_ID = PrHsPrice_ID AND Dsptch_PrHsInit_ID = PrHsInit_ID AND Dsptch_PostOffice_ID = PostOffice_ID AND Dsptch_PrHsNN_ID = PrHsNN_ID AND DSPTCH_MMYY = '1008' ORDER BY Dsptch_Date, Prdca_Name, PostOffice_Name */
Plan ------------------------------------------------ PLAN (D2 NATURAL) PLAN JOIN (D1 NATURAL,PRDCA INDEX (RDB$PRIMARY3))
Adapted Plan ------------------------------------------------ PLAN (D2 NATURAL)
PLAN JOIN (D1 NATURAL,PRDCA INDEX (PK_PRDCA))
Query Time ------------------------------------------------ Prepare : 0.00 ms Execute : 14 875.00 ms Avg fetch time: 619.79 ms
Memory ------------------------------------------------ Current: 5 704 700 Max : 5 838 940 Buffers: 1 262
Operations ------------------------------------------------ Read : 0 Writes : 0 Fetches: 18 534 461
Enchanced Info: +--------------------------+-----------+-----------+-------------+---------+---------+---------+ | Table Name | Records | Indexed | Non-Indexed | Updates | Deletes | Inserts | | | Total | reads | reads | | | | +--------------------------+-----------+-----------+-------------+---------+---------+---------+ | DSPTCH| 0 | 0 | 9071600 | 0 | 0 | 0 | | PRDCA| 0 | 328 | 0 | 0 | 0 | 0 | +--------------------------+-----------+-----------+-------------+---------+---------+---------+
Или где еще можно посмотреть статистику использования индексов?
-
Извините лишнее скопировалось :о((
-
> Sergey13 © (21.11.08 12:07) [4]
Без ORDER BY время выполнения увеличилось с 15 сек, до почти 18 сек. С ORDER BY пока не рискнул запускать. Чтобы долго не ждать.
-
> Еще приведи статистику использования индексов при выполнении > запроса
Прошу прощения. Я сделал "большую" вставку с быстрого запроса, т.е. без ORDER BY. Вы мне скажите, я правильно хотя бы выбрал информацию с закладки: Анализ производительности -> 2.Additional Если это то, о чем Вы просили, то я запущу "долгий" запрос и пришлю это же снова.
-
> Таблицы у меня без индексов
Каких же чудес ты тогда ждешь, если их нет ?! Чудес не жди, их не будет, пока не будет нужных индексов.
-
> я правильно хотя бы выбрал информацию с закладки: Анализ > производительности -> 2.Additional
Да, правильно.
-
> пока не будет нужных индексов.
Посоветуйте, пожалуйста, какой индекс тогда лучше сделать? По Dsptch_Prdca_ID, или Dsptch_Prdca_ID + Dsptch_Date? И как их тогда надо использовать в запросе?
-
индексы нужны нато, по каким полям сортировка + по каким полям соединение таблиц
-
Приведи подробную структуру обеих таблиц с описанием назначения каждого из их полей ..
-
а вот такого вида запрос в 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, поэтому ее игнорировал, но по смыслу, сам стиль, объединение с подзапросом пройдет? (если пройдет, то все лучше/быстрее будет один вызов подзапроса чем на каждую интерацию)
-
Извините за задержку, поздравляли сотрудника с днем рождения :о) Однако... Структуру привожу из скрипта таблиц: 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) );
-
А где описание и назначение каждого из полей ?
-
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.
-
> sniknik (21.11.2008 13:50:14) [14]
А ИБ6 поддерживает вложеные запросы.
-
> sniknik (21.11.2008 13:50:14) [14]
Кстати ты помнишь в ветке где категорически рекомендуют начинающим ИБ и его клоны, так вот отсутствие вложеных запросов одназначно закрыло мне путь к этой СУБД.
|