![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужно ускорить выполнение запроса. [D7, IB6.x]
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)