powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Оптимизация запроса.
5 сообщений из 5, страница 1 из 1
Оптимизация запроса.
    #38517045
Николаич_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть запрос, который использует процедуру. Без использования процедуры все летает. С использованием - тормоза полнейшие. В двух словах: в запросе с процедуры получает цену за единицу товара в зависимости от кол-ва товара в заказе.
Упрощенный запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select o.buy_price, o.whole_price, o.retail_price,
       cast(c.buy_price+mw.margin as integer) as catalog_whole_price,
       rp.o_retail_price as catalog_retail_price
from trd_orders_units ou
join trd_orders o on o.id=ou.id_order
join trd_catalog c on c.id=o.id_catalog
join trd_product_types pt on pt.id=c.id_product_type
left join trd_margin_wholesale mw on mw.id_firm=c.id_firm and mw.id_product_type=c.id_product_type
left join p_get_retail_price(o.order_num, o.id_catalog, c.id_firm, c.buy_price+mw.margin) rp on 1=1
where o.order_num=:order_num


Процедура:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
create or alter procedure P_GET_RETAIL_PRICE (
    I_ORDER_NUM D_INTEGER,
    I_ID_CATALOG D_ID,
    I_ID_FIRM D_ID,
    I_WHOLESALE_PRICE D_PRICE)
returns (
    O_RETAIL_PRICE D_PRICE)
as
declare variable V_MARGIN D_PRICE;
declare variable V_QUANTITY D_INTEGER;
begin
  select sum(ou.quantity)
  from trd_orders o
  join trd_orders_units ou on ou.id_order=o.id
  where o.order_num=:i_order_num
    and o.id_catalog=:i_id_catalog
  into :v_quantity;

  select m.margin
  from trd_margin_retail m
  where m.id_firm=:i_id_firm
    and m.quantity=(select max(m.quantity)
                    from trd_margin_retail m
                    where m.id_firm=:i_id_firm and m.quantity<=:v_quantity)
  into :v_margin;
  o_retail_price=i_wholesale_price+v_margin;
  suspend;
end


Готов выслушать всю критику по поводу написанного. Планы смотрел почти все по индексу. Наставьте на путь истинный, что я делаю не так.
...
Рейтинг: 0 / 0
Оптимизация запроса.
    #38517058
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Николаич_Упрощенный запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
. . .
select m.margin
  from trd_margin_retail m
  where m.id_firm=:i_id_firm
    and m.quantity=(select max(m.quantity)
                    from trd_margin_retail m
                    where m.id_firm=:i_id_firm and m.quantity<=:v_quantity)
  into :v_margin;

1) что будем делать, если в таблице trd_margin_retail число записей для некоторого ' max(m.quantity)' окажется больше одной ?
2) существует ли descending-индекс по таблице trd_margin_retail( id_firm, quantity ) ?
3) где вообще DDL таблиц и insert-команды с примерными данными ?
...
Рейтинг: 0 / 0
Оптимизация запроса.
    #38517062
Николаич_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо что откликнулись.
1. Не будет такого, т.к. в таблице стоит уникальное ограничение по этому полю.
Код: sql
1.
ALTER TABLE TRD_MARGIN_RETAIL ADD CONSTRAINT UNQ1_TRD_MARGIN_RETAIL UNIQUE (ID_FIRM, QUANTITY);


2. Индекс Ascending, при индексе Descending особой разницы не прочувствовал.
3. Думал до этого не дойдет, может что-то лежит на поверхности.
...
Рейтинг: 0 / 0
Оптимизация запроса.
    #38517066
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Николаич_,

попробуй замени

Код: sql
1.
2.
3.
4.
5.
6.
7.
  select m.margin
  from trd_margin_retail m
  where m.id_firm=:i_id_firm
    and m.quantity=(select max(m.quantity)
                    from trd_margin_retail m
                    where m.id_firm=:i_id_firm and m.quantity<=:v_quantity)
  into :v_margin;


на
Код: sql
1.
2.
3.
4.
5.
6.
  select first 1 m.margin
  from trd_margin_retail m
  where m.id_firm=:i_id_firm
    and m.quantity<=:v_quantity
order by m.quantity desc
  into :v_margin;
...
Рейтинг: 0 / 0
Оптимизация запроса.
    #38517197
Николаич_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Николаич_Планы смотрел почти все по индексу
Ключевым словом оказалось "почти". Медленная выборка была в запросе:
Код: sql
1.
2.
3.
4.
5.
6.
  select sum(ou.quantity)
  from trd_orders o
  join trd_orders_units ou on ou.id_order=o.id
  where o.order_num=:i_order_num
    and o.id_catalog=:i_id_catalog
  into :v_quantity;


На поля order_num и id_catalog нужне был уникальный индекс. Индекса от внешнего ключа было не достаточно, выборка была "натуральной". И вообще слегка переписал, стало летать. Всем спасибо кто откликнулся. Как говориться пообщаешься с умными людьми и все получится.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Оптимизация запроса.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]