Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос. / 8 сообщений из 8, страница 1 из 1
22.05.2015, 07:50
    #38965882
alc0g0l1c
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
Добрый день.
Помогите оптимизировать запрос.
Сам запрос очень большой поэтому напишу так сказать его идею (макет или план запроса, не знаю как обозвать) :)

Вот скажем пример запроса.
Из таблицы <ПЛАТЕЛЬЩИКИ> мы выбираем последний предоставленный документ по плательщику из которого берем долг плательщика. У каждого плательщика может дата предоставления документа отличаться. (недавно данный вопрос мне подсказали тут )

Из таблицы Б которую мы присоединяем LEFT JOIN-ом выбираем сумму платежей по данному плательщику.
Но сумму надо суммировать от даты последнего документа.

В итоге нам нужно получить должен плательщик или нет, это сумма долга - сумма платежей взятая от даты предоставления последнего документа

Код: 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.
29.
30.
select
select 
  t1.*
  from <ПЛАТЕЛЬЩИКИ> t1
  left join <ПЛАТЕЛЬЩИКИ> t2
    on t1.num = t2.num
   and t1.dt < t2.dt
 where t2.num is null;

LEFT JOIN
(
select
    B.PlatID,
    sum(B.platezh)
from
    TablePlatezh B
where
    B.dataPlat >= (  
  select
  select 
  t1.*
  from <ПЛАТЕЛЬЩИКИ> t1
  left join <ПЛАТЕЛЬЩИКИ> t2
    on t1.num = t2.num
   and t1.dt < t2.dt
 where t2.num is null
          t1.PlatID = B.PlatID
                         )
)
on t1.PlatID = B.PlatID



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

Подскажите как можно ускорить выполнение запроса.
...
Рейтинг: 0 / 0
22.05.2015, 09:12
    #38965945
Помогите оптимизировать запрос.
alc0g0l1c,

можно заюзать оконные функции.

ты бы лучше вместо макета запроса привел бы макет тестовых данных и желаемый результат на них. дело бы с помощью пошло быстрее...
...
Рейтинг: 0 / 0
22.05.2015, 10:02
    #38966007
alc0g0l1c
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
Добрый Э - Эх,

хорошо, так сказать тестовые данные...

Таблица с Документами (точнее с id на таблицу с долгами по документу)
user_idupdate_yearupdate_monthDoc_id720143172014627201412372015341120153511201566182015371920153819201569212014310212014911

Таблица с документами (долг по документам)
Doc_idDolgSum15122223452434556546123753458539345108711344

А так же есть таблица с платежами
Plat_iduser_idData_platplatez172015-02-17117272015-03-22274372015-03-3187472015-04-172475112015-06-151006112015-07-112007182015-01-2525008182015-03-1425009192015-04-1630010192015-06-1740011212015-03-1130012212015-05-21400

В итоге получаем следующее выбираем последний документ (с максимальной датой), с нему с лева подтягиваем долг по документу, и остается так же с лева подтянуть сумму платежей начиная с даты после получения последнего документа.
Должна получится следующая таблица

user_idupdate_yearupdate_monthDoc_idDolgSum(сумма платежей) platez7201534345247112015661232001820153753450192015693450212014911344700

Так же кроме этих таблиц к первой left join-ом добавляется несколько таблиц с адресами плательщиков, с телефонами и т.д.
но они на скорость выборки не влияют.
...
Рейтинг: 0 / 0
22.05.2015, 11:37
    #38966138
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
alc0g0l1c,

Добрый день.
Как-то так
Код: 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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
with doc1 (user_id, update_year, update_month, Doc_id) as (values
  (7,   2014,    3,   1)
, (7,   2014,    6,   2)
, (7,   2014,    12,  3)
, (7,   2015,    3,   4)
, (11,  2015,    3,   5)
, (11,  2015,    6,   6)
, (18,  2015,    3,   7)
, (19,  2015,    3,   8)
, (19,  2015,    6,   9)
, (21,  2014,    3,   10)
, (21,  2014,    9,   11)
)
, doc2 (Doc_id, DolgSum) as (values
  (1,   512)
, (2,   22)
, (3,   452)
, (4,   345)
, (5,   654)
, (6,   123)
, (7,   5345)
, (8,   53)
, (9,   345)
, (10,  87)
, (11,  344)
)
, payments (Plat_id, user_id, Data_plat, platez) as (values
  (1,   7,   date('2015-02-17'),  117)
, (2,   7,   date('2015-03-22'),  274)
, (3,   7,   date('2015-03-31'),  87)
, (4,   7,   date('2015-04-17'),  247)
, (5,   11,  date('2015-06-15'),  100)
, (6,   11,  date('2015-07-11'),  200)
, (7,   18,  date('2015-01-25'),  2500)
, (8,   18,  date('2015-03-14'),  2500)
, (9,   19,  date('2015-04-16'),  300)
, (10,  19,  date('2015-06-17'),  400)
, (11,  21,  date('2015-03-11'),  300)
, (12,  21,  date('2015-05-21'),  400)
)
select d1.user_id, d1.update_year, d1.update_month, d1.Doc_id, value(d2.dolgsum, 0) dolgsum
, value((
  select sum(p.platez) platez
  from payments p
  where p.user_id=d1.user_id and (year(p.data_plat)*100+month(p.data_plat)) > (d1.update_year*100+d1.update_month)
), 0) platez
from (
select d.*, rownumber() over (partition by user_id order by update_year desc, update_month desc) rn_
from doc1 d
) d1
left join doc2 d2 on d2.doc_id=d1.doc_id
where d1.rn_=1 


P.S.:
Желательно всё же данные предоставлять не в виде табличек, а в виде sql команд создания таблиц, чтобы люди не тратили время на подготовку данных для запроса.
Например,
[create | declare global temporary] doc1 (...);
insert into doc1 values (...), ..., (...);
...
...
Рейтинг: 0 / 0
25.05.2015, 11:50
    #38967686
alc0g0l1c
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
Mark Barinsteinalc0g0l1c,

Добрый день.
Как-то так
Код: 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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
with doc1 (user_id, update_year, update_month, Doc_id) as (values
  (7,   2014,    3,   1)
, (7,   2014,    6,   2)
, (7,   2014,    12,  3)
, (7,   2015,    3,   4)
, (11,  2015,    3,   5)
, (11,  2015,    6,   6)
, (18,  2015,    3,   7)
, (19,  2015,    3,   8)
, (19,  2015,    6,   9)
, (21,  2014,    3,   10)
, (21,  2014,    9,   11)
)
, doc2 (Doc_id, DolgSum) as (values
  (1,   512)
, (2,   22)
, (3,   452)
, (4,   345)
, (5,   654)
, (6,   123)
, (7,   5345)
, (8,   53)
, (9,   345)
, (10,  87)
, (11,  344)
)
, payments (Plat_id, user_id, Data_plat, platez) as (values
  (1,   7,   date('2015-02-17'),  117)
, (2,   7,   date('2015-03-22'),  274)
, (3,   7,   date('2015-03-31'),  87)
, (4,   7,   date('2015-04-17'),  247)
, (5,   11,  date('2015-06-15'),  100)
, (6,   11,  date('2015-07-11'),  200)
, (7,   18,  date('2015-01-25'),  2500)
, (8,   18,  date('2015-03-14'),  2500)
, (9,   19,  date('2015-04-16'),  300)
, (10,  19,  date('2015-06-17'),  400)
, (11,  21,  date('2015-03-11'),  300)
, (12,  21,  date('2015-05-21'),  400)
)
select d1.user_id, d1.update_year, d1.update_month, d1.Doc_id, value(d2.dolgsum, 0) dolgsum
, value((
  select sum(p.platez) platez
  from payments p
  where p.user_id=d1.user_id and (year(p.data_plat)*100+month(p.data_plat)) > (d1.update_year*100+d1.update_month)
), 0) platez
from (
select d.*, rownumber() over (partition by user_id order by update_year desc, update_month desc) rn_
from doc1 d
) d1
left join doc2 d2 on d2.doc_id=d1.doc_id
where d1.rn_=1 


P.S.:
Желательно всё же данные предоставлять не в виде табличек, а в виде sql команд создания таблиц, чтобы люди не тратили время на подготовку данных для запроса.
Например,
[create | declare global temporary] doc1 (...);
insert into doc1 values (...), ..., (...);
...

Спасибо огромное. Работает, я даже удивился как быстро выбирается)))
...
Рейтинг: 0 / 0
25.05.2015, 16:22
    #38968006
alc0g0l1c
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
Mark Barinstein,
а в вашем варианте, можно как нибудь обойтись без rownumber(), просто надо этот запрос еще и на cache перенести,а там функции rownumber() нету, не подскажите как можно без нее обойтись!

P.S.: на db2 запрос работает замечательно, большое спасибо! :-)
...
Рейтинг: 0 / 0
25.05.2015, 16:49
    #38968035
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
alc0g0l1cа в вашем варианте, можно как нибудь обойтись без rownumber(), просто надо этот запрос еще и на cache перенести,а там функции rownumber() нету, не подскажите как можно без нее обойтись!
Код: sql
1.
2.
3.
4.
5.
...
from doc1 d1
join (select user_id, max(update_year*100 + update_month) yyyymm  from doc1 group by user_id) g
on d1.user_id=g.user_id and d1.update_year*100 + d1.update_month = g.yyyymm
left join doc2 d2 on d2.doc_id=d1.doc_id
...
Рейтинг: 0 / 0
25.05.2015, 17:25
    #38968083
alc0g0l1c
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос.
Mark Barinstein,

Спасибо, за опперативный ответ. Завтра попробую. :-)
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос. / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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