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

dimm22 ©   (2004-04-05 12:10:00) 

У меня 4 таблицы, и надо мне получить данные из таблиц 1 и 2 путём группирования (group by) таблицы 1 и присоединением(join) к результату полей из таблицы 2. С таблицами 3 и 4 точно такая же ситуация(группирование (group by) таблицы 3 и присоединением(join) к результату полей из таблицы 4). А результат полученный из таблиц 1+2 надо объединить с результатом из таблиц 3+4. Группирование таблицы 1 и присоединение полей из таблицы 2, в моём конкретном случае, проходит порядка 4 секунд. Та же операция с таблицами 3 и 4 порядка 7 секунд. Но если в одном запросе попробовать сделать 1+2 join 3+4,  то получается очень долго (ждал час – не дождался, вырубил.)  Индексы по группируемым и объединяемым полям присутствуют. Сейчас вышел из положения созданием псевдо временной таблицы, в которую пишу результаты запроса к 1+2 таблице, а потом уж объединяю её  с  результатом полученным из 3+4 таблицы. Всё бы ничего, но вставка и удаление в псевдо временную таблицу 5 000- 18 000 записей, не кажется мне хорошим решением. Может можно как-нибудь заставить оптимизатор сначала выполнить запрос 1+2, потом 3+4, а потом уж объединить результаты?


serge35   (2004-04-05 14:34:00) [21]

А делать временные таблицы может и неправильно,
а вот постоянную я бы сделал и возможно, что не одну.


serge35   (2004-04-05 14:33:00) [22]

Я не знаю, поддерживает ли IB курсоры, но с ними получилось бы намного быстрее.


dimm22   (2004-04-05 14:33:00) [23]


> Shaman ©   (05.04.04 14:17) [10]

Понятное дело это приведёт к ускорению запроса, но дело в том, что не могу я так сделать. Пока я не сгруппировал у меня просто нет данных для join.

Кстати слышал краем уха, что в Ibase 7.1 есть временные таблицы. Так ли это?


Shaman   (2004-04-05 14:17:00) [24]

Сначала выполняй join, а потом группируй


dimm22   (2004-04-05 12:46:00) [25]

Кстати, где то месяц назад велась полемика насчёт полезности временных таблиц. Ну так вот на моём опыте могу сказать, что они полезны, во всяком случае, для оптимизации запросов.


Fay   (2004-04-05 12:44:00) [26]

2dimm22   (05.04.04 12:41) [7]
Быстрее и намного. Любым (корректным) способом. С индексами ли, бе них ли... Потому, что IB - тормоз.


dimm22   (2004-04-05 12:41:00) [27]


> Fay ©   (05.04.04 12:27) [5]

Ну не думаю я, что без использования временных таблиц Oracle или MSSQL сделает это намного быстрее. Там проблема в том, что вторая часть запроса (таблицы 3+4) выполняется каждый раз с новым значением поля, по которому идёт его объединение с результатами из таблиц 1+2. А хотелось бы добится выполнения 1+2, потом 3+4, а потом уж выполнение объединения с этих результатов.


> Курдль ©   (05.04.04 12:34) [6]

А это мысль. Спасибо.


Курдль   (2004-04-05 12:34:00) [28]

Трудно "навскидочку" понять, чего Вы добивались, но не попробовать ли подменить группировку конструкцией

select
 field1,
 field2,
...
 (select SUM(field3) from table2 ...)  as field3
...
from table1


Fay   (2004-04-05 12:27:00) [29]

2dimm22
Да хоть как. Всё равно будет намного быстрее.


dimm22   (2004-04-05 12:27:00) [30]

Ну на самом деле сейчас это оформлено в 2 процедуры.
1)CREATE PROCEDURE INVENT_SKLADA (
   PRMDATA_P DATE)
RETURNS (
   QUANTITY DECIMAL(11,2),
   ID_GOODS INTEGER,
   ART VARCHAR(25),
   NAME_R VARCHAR(45),
   PRICE_SALE DOUBLE PRECISION,
   ID_GOODS2 INTEGER)
AS
begin
for SELECT sum(deposit.quantity), deposit.id_goods, goods.art, goods.name_r, goods.price_sale, goods.id_goods
   FROM goods inner join deposit  on  deposit.id_goods= goods.id_goods where deposit.data_p<=:prmdata_p
   group by deposit.id_goods, goods.art,goods.name_r,goods.price_sale,goods.id_goods
   into    :QUANTITY,:ID_GOODS,:ART,:NAME_R,:PRICE_SALE,:ID_GOODS2
   do
       begin
       suspend;
       end
end
2)CREATE PROCEDURE SKLAD_SITUATION (
   PRM_DATA DATE)
RETURNS (
   QUANTITY DECIMAL(11,2),
   ART VARCHAR(25),
   NAME_R VARCHAR(45),
   PRICE_SALE DOUBLE PRECISION,
   ID_GOODS2 INTEGER)
AS
begin
   execute procedure rashod_sklad_procedure(:prm_data);
   for
    select invent_sklada.id_goods2, invent_sklada.art,  invent_sklada.name_r, invent_sklada.price_sale, invent_sklada.quantity+rashod_sklad_tmp.quantity  from invent_sklada('01.03.2004')
    left join rashod_sklad_tmp  on invent_sklada.id_goods2=rashod_sklad_tmp.id_goods
    into  :id_goods2, :art,  :name_r, :price_sale, :quantity
    do
      begin
       suspend;
  end
end
А потом уж их объединение по полю id_goods, но был и один запрос - результат тот же.


dimm22   (2004-04-05 12:19:00) [31]


> Fay ©

А там, что? Временными таблицами пользуешься?


Курдль   (2004-04-05 12:15:00) [32]

А не весь запрос глянуть можно?


Fay   (2004-04-05 12:13:00) [33]

Это, конечно, это не решение, но по опыту знаю - очень хорошо помогает переход на Oracle или MSSQL. 8)


Страницы:   1 2

Наверх

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