简体   繁体   中英

How to Improve Performance of sql query

The Table

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')); 
 `

Now, The query

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

I want to know if I could improve the performance of this SQL Query?

If you notice the code, you can see that there is a 'Where' statement that is taking results from various dates groups. Most of the query is repetitive except the where clause.

Is there a way to optimize the query? In terms of performance and number of lines.

Expected Output Format: I can code the format part, but, That's the idea 在此处输入图片说明

Looks like you are trying to get quarterly totals/quantities. Could be simplified doing sum( case/when ).

SQL Fiddle Result

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

and definitely have an index on ( date, key )… The date field to optimize the WHERE clause, the KEY to optimize the group by

Doing all in one will prevent missing numbers such as an item not sold in first quarter but IS sold in second, third or fourth, it would otherwise be left out of the final results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM