Как улучшить производительность SQL-запроса - PullRequest
0 голосов
/ 16 апреля 2019

Таблица

CREATE TABLE ABC(key number(5), orders number(5), cost number(5), dat date);
insert into ABC (key, orders, cost, dat) values (1, 3, 5, to_date('10-01- 
2017', 'mm-dd-yyyy'));
insert into ABC (key, orders, cost,dat) values (1, 5, 2, to_date('02-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (1, 6, 1, to_date('03-10- 
2017', 'mm-dd-yyyy'));
insert into ABC (key, orders, cost,dat) values (1, 7, 2, to_date('05-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (1, 8, 3, to_date('07-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (1, 3, 4, to_date('08-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 6, to_date('02-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 9, to_date('01-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 2 ,5, to_date('03-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 2, to_date('05-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 1, 1, to_date('06-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 4, 12, to_date('10-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 3, 9, to_date('01-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 2 ,5, to_date('05-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 3, 2, to_date('06-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 1, 1, to_date('07-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (3, 4, 12, to_date('11-10- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost, dat) values (1, 3, 5, to_date('10-01- 
2017', 'mm-dd-yyyy'));
insert into ABC (key, orders, cost,dat) values (1, 5, 2, to_date('02-17- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (1, 6, 1, to_date('03-18- 
2017', 'mm-dd-yyyy'));
insert into ABC (key, orders, cost,dat) values (1, 7, 2, to_date('05-14- 
2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (1, 8, 3, to_date('07-13- 
 2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (1, 3, 4, to_date('08-12- 
 2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 6, to_date('02-11- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 9, to_date('01-15- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 2 ,5, to_date('03-14- 
2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 3, 2, to_date('05-18- 
 2017', 'mm-dd-yyyy')); 
insert into ABC (key, orders, cost,dat) values (2, 1, 1, to_date('06-19- 
2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (3, 4, 12, to_date('10-11- 
 2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (3, 3, 9, to_date('01-12- 
 2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (3, 2 ,5, to_date('05-16- 
 2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (3, 3, 2, to_date('06-17- 
 2017', 'mm-dd-yyyy')); 
 insert into ABC (key, orders, cost,dat) values (3, 1, 1, to_date('07-12- 
 2017', 'mm-dd-yyyy')); 
  insert into ABC (key, orders, cost,dat) values (3, 4, 12, to_date('12-11- 
  2017', 'mm-dd-yyyy')); 
 `

Теперь запрос

with
one as 
(select t.key, sum(t.cost) as tot, sum(t.orders) as qty from table t
where t.date >= to_date('01-01-2017','mm-dd-yyyy') and 
t.date < to_date('04-01-2017','mm-dd-yyyy')
group by t.key),
two as 
(select t.key, sum(t.cost) as tot, sum(t.orders) as qty from table t
where t.date >= to_date('04-01-2017','mm-dd-yyyy') and 
t.date < to_date('07-01-2017','mm-dd-yyyy')
group by t.key),
three as
(select t.key, sum(t.cost) as tot, sum(t.orders) as qty from table t
where t.date >= to_date('07-01-2017','mm-dd-yyyy') and 
t.date < to_date('10-01-2017','mm-dd-yyyy')
group by t.key),
four as
(select t.key, sum(t.cost) as tot, sum(t.orders) as qty from table t
where t.date >= to_date('10-01-2017','mm-dd-yyyy') and 
t.date < to_date('01-01-2018','mm-dd-yyyy')
group by t.key)
select o.key, o.tot, o.qty, s.tot, s.qty, t.tot, t.qty, f.tot,f.qty 
from one o
left join two s on s.key = o.key
left join three t on t.key = o.key
left join four f on f.key = o.key

Я хочу знать, могу ли я повысить производительность этого SQL-запроса?

Если выобратите внимание на код, вы можете видеть, что есть оператор «Где», который получает результаты из разных групп дат.Большая часть запроса повторяется, кроме предложения where.

Есть ли способ оптимизировать запрос?С точки зрения производительности и количества строк.

Ожидаемый формат вывода: я могу кодировать часть формата, но это идея enter image description here

1 Ответ

2 голосов
/ 15 мая 2019

Похоже, вы пытаетесь получить квартальные итоги / количества.Можно упростить, выполнив сумму (случай / когда).

Результат SQL Fiddle

select 
        t.key, 
        sum( case when t.dat >= Tmp.Q1From and t.dat < Tmp.Q1End then t.cost else 0 end ) as Q1Tot, 
        sum( case when t.dat >= Tmp.Q1From and t.dat < Tmp.Q1End then t.orders else 0 end ) as Q1Qty,
        sum( case when t.dat >= Tmp.Q1End and t.dat < Tmp.Q2End then t.cost else 0 end ) as Q2Tot, 
        sum( case when t.dat >= Tmp.Q1End and t.dat < Tmp.Q2End then t.orders else 0 end ) as Q2Qty,
        sum( case when t.dat >= Tmp.Q2End and t.dat < Tmp.Q3End then t.cost else 0 end ) as Q3Tot, 
        sum( case when t.dat >= Tmp.Q2End and t.dat < Tmp.Q3End then t.orders else 0 end ) as Q3Qty,
        sum( case when t.dat >= Tmp.Q3End and t.dat < Tmp.Q4End then t.cost else 0 end ) as Q4Tot, 
        sum( case when t.dat >= Tmp.Q3End and t.dat < Tmp.Q4End then t.orders else 0 end ) as Q4Qty
    from 
        ABC t,
           ( select 
                   to_date('01-01-2017', 'mm-dd-yyyy') Q1From,
                   to_date('04-01-2017', 'mm-dd-yyyy') Q1End,
                   to_date('07-01-2017', 'mm-dd-yyyy') Q2End,
                   to_date('10-01-2017', 'mm-dd-yyyy') Q3End,
                   to_date('01-01-2018', 'mm-dd-yyyy') Q4End
                from 
                   dual ) Tmp
    where 
            t.dat >= to_date('01-01-2017', 'mm-dd-yyyy')
        and t.dat < to_date('01-01-2018', 'mm-dd-yyyy')
    group by 
        t.key

и определенно иметь индекс (дата, ключ)… Поле датычтобы оптимизировать предложение WHERE, КЛЮЧ для оптимизации группы на

Выполнение всех в одном предотвратит пропущенные числа, такие как предмет, не проданный в первом квартале, но проданный во втором, третьем или четвертом, иначеопущены из окончательных результатов.

...