in reply to Re: Perl CGI timeout
in thread Perl CGI timeout

StrebenMonch: Thanks for the ideas.
Optimized the SQL is what i have been thinking about.
I attached the SQL here, I could only see to eliminate the calculation of the cost where I used 'case' to check null value and use sum function again. Please correct me if you think any other ones could be done in the Perl.

After bind_columns, then use loop and array to do the summation?
select
mvmnt_data.region
,store_name
,nvl(i_a.nat_upc,i_b.nat_upc)
,nvl(i_a.long_description,i_b.long_description)
,nvl(i_a.item_size,i_b.item_size)
,nvl(i_a.item_uom,i_b.item_uom)
,vsi.vend_item_num
,salesUnits
,salesDollars
,case_size
,cost
,ps.ps_prod_subteam
from
(select wm.upc,sum(wm.mvmnt_units) salesUnits
,sum(wm.mvmnt_dollars) salesDollars
,wm.store
,wm.pos_dept
,wm.case_size
,sum(round (case when wm.case_size is null or
wm.case_cost=0
then null
else (wm.case_cost/wm.case_size) *
wm.mvmnt_units end, +3)) cost
,s.store_name
,s.region
from stella.mvmnt_wkly wm,vim.store@vim s
where wm.mvmnt_date between to_date
('10/01/2004', 'mm/dd/yyyy')and to_date
('10/03/2004', '/mm/dd/yyyy')
and wm.store in ('10036')
and wm.store=s.ps_bu
--and wm.upc='000000015232'
and wm.pos_dept='0110'
group by wm.case_size
,s.region
,wm.pos_dept,
wm.upc
,wm.store
,s.store_name) mvmnt_data,
vim.item_region@vim ir,
vim.item_master@vim i_a,
vim.item_master@vim i_b,
vim.reg_pos_dept_ref@vim rpdr
,vim.ps_team_ref@vim ps
,vim.vendor_store_item@vim vsi
where mvmnt_data.region=ir.region(+)
and mvmnt_data.upc=substr(ir.upc(+),-12,12)
and substr(ir.nat_upc, 12, 12)=substr(i_a.nat_upc(+),-
12,12)
and mvmnt_data.upc=substr(i_b.nat_upc(+),-12,12)
and mvmnt_data.region=rpdr.region(+)
and mvmnt_data.pos_dept=trim(leading 0 from rpdr.pos_dept
(+)) and rpdr.pos_dept=ps.pos_dept
and rpdr.region=ps.region
and mvmnt_data.store=ps.ps_bu
and mvmnt_data.upc=substr(vsi.upc,-12,12)
and vsi.region=ps.region
and vsi.ps_bu=mvmnt_data.store
and vsi.v_auth_status='P'
Jewang

Replies are listed 'Best First'.
Re^3: Perl CGI timeout
by StrebenMönch (Beadle) on Dec 03, 2004 at 14:42 UTC
    This is where I might try to break this into 2 selects. (to the more experienced SQL people, feel free to correct me)

    Query 1
    ===========================================================
    SELECT ir.region 
          ,ir.upc
          ,i_b.nat_upc
          ,rpdr.region
          ,rpdr.pos_dept
          ,ps.pos_dept
          ,ps.ps_bu
          ,vsi.upc
          ,vsi.ps_bu
    
          ,store_name
          ,NVL(i_a.nat_upc,i_b.nat_upc)
          ,NVL(i_a.long_description,i_b.long_description)
          ,NVL(i_a.item_size,i_b.item_size)
          ,NVL(i_a.item_uom,i_b.item_uom)
          ,vsi.vend_item_num
          ,ps.ps_prod_subteam
      FROM vim.item_region@vim       ir
          ,vim.item_master@vim       i_a
          ,vim.item_master@vim       i_b
          ,vim.reg_pos_dept_ref@vim  rpdr
          ,vim.ps_team_ref@vim       ps
          ,vim.vendor_store_item@vim vsi
     WHERE substr(ir.nat_upc, 12, 12)=substr(i_a.nat_upc(+),-12,12)
       AND rpdr.pos_dept     = ps.pos_dept
       AND rpdr.region       = ps.region
       AND vsi.region        = ps.region
       AND vsi.v_auth_status = 'P'
    
    ===========================================================
    The first 9 columns in the select are new and will be used in the second select.

    Query 2
    ===========================================================
    SELECT mvmnt_data.region
          ,wm.upc
          ,sum(wm.mvmnt_units)    AS salesUnits
          ,sum(wm.mvmnt_dollars) AS salesDollars
          ,wm.store
          ,wm.pos_dept
          ,wm.case_size
          ,SUM(ROUND (CASE WHEN wm.case_size IS NULL OR wm.case_cost=0 THEN NULL 
                           ELSE (wm.case_cost/wm.case_size) * wm.mvmnt_units end, +3)) AS cost
          ,s.store_name
      FROM stella.mvmnt_wkly wm
          ,vim.store@vim s
     WHERE mvmnt_data.region=ir.region(+)
       AND mvmnt_data.upc      = ?
       AND mvmnt_data.upc      = ?
       AND mvmnt_data.region   = ?
       AND mvmnt_data.pos_dept = ?
       AND mvmnt_data.store    = ?
       AND mvmnt_data.upc      = ?
       AND mvmnt_data.store    = ?
       AND wm.mvmnt_date between to_date('10/01/2004', 'mm/dd/yyyy') and to_date('10/03/2004', '/mm/dd/yyyy')
       AND wm.store           in ('10036')
       AND wm.store            = s.ps_bu
       AND wm.pos_dept         = '0110'
     GROUP BY wm.case_size
             ,s.region
             ,wm.pos_dept
             ,wm.upc
             ,wm.store 
             ,s.store_name
    
    ===========================================================
    So what I would do is call the first query then while looping through it you can do the proper substr on the data. And also call query 2.

    I would try to optimize query 2 as much as possable by creating indexs if need be and looking at an execution plan. For example this is what I use for MySQL

    deleteplan.sql
    ===========================================================
    delete from plan_table
     where statement_id = 'TEST'
    
    /
    commit
    /
    
    ===========================================================

    test.sql
    ===========================================================
    @deleteplan
    
    EXPLAIN PLAN set statement_id = 'TEST' for
    SQL STATEMENT GOES HERE
    
    /
    
    @getplan
    
    ===========================================================

    getplan.sql (there is some other information you can get from the plan_table, but this is all I need most of the time)
    ===========================================================
    select operation, options, object_name, cost, cardinality, TO_CHAR(timestamp, 'HH:MM:SS')
      from plan_table
     where statement_id = 'IFXTEST'
    start with id = 0
    connect by prior id=parent_id and prior statement_id = statement_id
    
    /
    
    ===========================================================
    So I just put my SQL in test.sql and run it to get my execution plan. From there you can see where your problems are.

    S t r e b e n M ö n c h