powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как ускорить запрос с between'ом
11 сообщений из 11, страница 1 из 1
Как ускорить запрос с between'ом
    #32553374
MVal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Есть у меня две процедуры, возвращающие наборы данных.

ALTER PROCEDURE GETUPL (
ME INTEGER)
RETURNS (
PR INTEGER,
S NUMERIC(15,2))
AS
begin
for
select pr, sum(s) as s from upl where me=:me group by pr
union
select pr, CAST (0 AS numeric(15,2)) as s from sppr where pr not in (select pr from upl where me=:me)
into :pr, :s
do
suspend;
end
и

ALTER PROCEDURE GETUPLBYINT (
ME1 INTEGER,
ME2 INTEGER)
RETURNS (
PR INTEGER,
S NUMERIC(15,2))
AS
begin
for
select pr, sum(s) as s from upl where me between :me1 and :me2
group by pr
union
select pr, CAST (0 AS numeric(15,2)) as s from sppr where pr not in (select pr from upl where me between :me1 and :me2)
into :pr, :s
do
suspend;
end

Где - sppr - таблица-список всех аббанентов. Ключевое поле - pr.
Upl - оплата, произведенная абанентом pr в месяце me.
Первая процедура возвращает оплату за определенный месяц (параметр me), для тех, у кого ее нет возвращает нули. Вторая - то же самое, только за период с me1 до me2.
Первая процедура работает бовольно быстро, а вторая во много раз медленнее (причем не зависимо от расстояния между me1 и me2).
Имею индексы по Sppr.pr, upl.pr, upl.me, upl.(pr,me).
Как можно ускорить этот процес?
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32553455
Voha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://ibase.ru/devinfo/dontdoit.htm пункт 15. IN-это и есть тормаза процедуры
попробуй поменять чтобы это избежать
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32553727
Dremuchij Forester
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуй так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE PROCEDURE GETUPL (
    ME INTEGER)
RETURNS (
    PR INTEGER,
    S NUMERIC( 15 , 2 ))
AS
begin
 for SELECT pr FROM upl
  INTO :PR
 do
 begin
  S =  0 ;
  SELECT SUM(s) as s FROM UPL
   WHERE me = :me
    AND  pr = :pr
   GROUP BY pr
   INTO :S;
  suspend;
 end;
end

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE PROCEDURE GETUPLBYINT (
    ME1 INTEGER,
    ME2 INTEGER)
RETURNS (
    PR INTEGER,
    S NUMERIC( 15 , 2 ))
AS
begin
 for SELECT pr FROM upl
  INTO :PR
do
 begin
  S =  0 ;
  SELECT SUM(s) as s FROM UPL
   WHERE me BETWEEN :ME1 AND :ME2
    AND  pr = :PR
   GROUP BY pr
   INTO :S;
  suspend;
 end;
end

Производительность не оценивал, но IN(SELECT...) это точно тормоз.
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32553814
doroshka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С IN - все понятно. Основный тормоза от него, но вот, кстати, интересно UNION как-то влтяет на производительность. Я бы, например, в таком случае:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
.....
for
select pr, sum(s) as s from upl where me=:me group by pr
union
select pr, CAST ( 0  AS numeric( 15 , 2 )) as s from sppr where pr not in (select pr from upl where me=:me)
into :pr, :s
do
suspend;
....

Написал бы так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
....
for select pr, sum(s) as s from upl where me=:me group by pr
     into :pr, :s
do  
  suspend;

s= 0 ;
for select pr from sppr where pr not in (select pr from upl where me=:me)
     into :pr
do
   suspend;
....
Есть ли какая-то разница по скорости? Или это те же яйца только с боку?
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32559992
MVal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем, кто откликнулся.
Как не странно (хотя, наверное ничего странного в этом нет) производительность данного (и других ему подобных) запросов многократно возрасла заменой IB 6.0.1 на FB 1.5. Видимо он более корректно работает с индексами.

2 Dremuchij Forester Спасибо за вариант, только я толком не понял, что он там возвращает (видимо не то, что я хотел). А хоте я так просуммировать все S с группировкой по PR из UPL и дополнить ее теми номерами ( PR ), которых нет в UPL .

2 doroshka Спасибо. Без union'а действительно полегче. Так "оригинальный" запром выполняется в среднем за 70 мс, а твой - за 10.
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32560270
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MValСпасибо. Без union'а действительно полегче. Так "оригинальный" запром выполняется в среднем за 70 мс, а твой - за 10.

Я бы на твоем месте изначально заменил UNION на UNION ALL и получил бы те же самые 10 мс.
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32561054
doroshka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dimitr...заменил UNION на UNION ALL и получил бы те же самые 10 мс.
Спасибо, это и интересно было узнать.
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32561124
Dremuchij Forester
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ага, накосячил. Надо в обеих процедурах
...
for SELECT pr FROM /* не upl , а*/ sppr
INTO :PR
do
...
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32568944
MVal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2remuchij Forester
А вот теперь заработал как надо.
Что касается скорости выполнения то вариант doroshka (то же с union all) на FB 1.5 работает в полтара раза быстрее. Зато на IB 6 или на FB 1.0 твой вариант значительно быстрее (примерно раз в 100).
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32572637
Ярослав Татаренко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NOT IN замечательно меняется на NOT EXISTS, при этом значительно возрастает скорость, а еще лучше в данном случае на JOIN. UNION меняем на UNION ALL, правда нужно посмотреть на повторяемость результирующих записей.
...
Рейтинг: 0 / 0
Как ускорить запрос с between'ом
    #32572870
MVal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообщем то да. Вариант с not exist получше (почти в полтора раза быстрее).
Про union я уже давно понял, что был не прав.
Вообщем нет предела совершенству :-)
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как ускорить запрос с between'ом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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