How to Optimize SQL SELECT Statement for BOMP Product Structure

Release Date: 11/29/2017

Q - I used the following SQL SELECT statement to retrieve product structure from the BOMP module. Generally speaking, it works. But the performance is not what I would like it to be. Is there anyway to make it run faster?

SELECT PRD_STR_PAR_ITEM_NO, PAR.ITEM_DESC1, PAR.ITEM_DESC2, PRD_STR_SEQ_NO,
PRD_COMP_ITEM_NO, COMP.ITEM_DESC1 AS COMP_ITEM_DESC1,
COMP.ITEM_DESC2 AS COMP_ITEM_DESC2, PRD_STR_QTY_PER_PAR,
COMP.ITEM_UOM AS COMP_ITEM_UOM, COMP.ITEM_STD_COST AS 'Comp Cost',
PAR.ITEM_USER_DEF_CD, COMP.ITEM_STD_COST AS 'Assembly Cost', PAR.ITEM_DRAWING_REL_NO,
PAR.ITEM_ACTIVITY_CD, PRD_EFF_DATE, PRD_STR_OBSOLETE_DT
FROM (BMPRDSTR INNER JOIN IMITMFIL AS PAR 
ON PRD_STR_PAR_ITEM_NO = PAR.ITEM_NO)
INNER JOIN IMITMFIL AS COMP ON PRD_COMP_ITEM_NO = COMP.ITEM_NO
WHERE PAR.ITEM_ACTIVITY_CD <> 'O'
ORDER BY PRD_COMP_ITEM_NO;
 
A - I tested the above SQL statement with a database in which the BMPRDSTR.BTR file size is 63MB and the IMITMFIL.BTR file size is 130MB. The first time I ran this statement, it took 40 second to finish. The second time, because data is already cached in the server memory, it took only 5 second to finish. Even though 5 second is not a lot, I feel there's room for improvement. So I revised the SQL SELECT statement as follows:

SELECT PRD_STR_PAR_ITEM_NO, PAR.ITEM_DESC1, PAR.ITEM_DESC2, PRD_STR_SEQ_NO,
PRD_COMP_ITEM_NO, COMP.ITEM_DESC1 AS COMP_ITEM_DESC1,
COMP.ITEM_DESC2 AS COMP_ITEM_DESC2, PRD_STR_QTY_PER_PAR,
COMP.ITEM_UOM AS COMP_ITEM_UOM, COMP.ITEM_STD_COST AS 'Comp Cost',
PAR.ITEM_USER_DEF_CD, COMP.ITEM_STD_COST AS 'Assembly Cost', PAR.ITEM_DRAWING_REL_NO,
PAR.ITEM_ACTIVITY_CD, PRD_EFF_DATE, PRD_STR_OBSOLETE_DT
FROM  IMITMFIL AS PAR, BMPRDSTR, IMITMFIL AS COMP 
WHERE PAR.ITEM_NO IN (SELECT DISTINCT PRD_STR_PAR_ITEM_NO FROM BMPRDSTR) 
AND PAR.ITEM_ACTIVITY_CD <> 'O'
AND PAR.ITEM_NO = BMPRDSTR.PRD_STR_PAR_ITEM_NO
AND PRD_COMP_ITEM_NO = COMP.ITEM_NO
ORDER BY PRD_COMP_ITEM_NO;

This SQL SELECT statement took about 1 second to finish. Why is it faster? As you can see we moved the INNER JOIN out of the FROM clause to the WHERE clause as the last two conditions. In the WHERE clause, we began with the following condition:

      WHERE PAR.ITEM_NO IN (SELECT DISTINCT PRD_STR_PAR_ITEM_NO FROM BMPRDSTR)  

This narrowed down the first item set to the parent item only. Then it further excluded the obsolete parent items by using   PAR.ITEM_ACTIVITY_CD <> 'O'. Now this is a smaller subset. We then used it to join with the BMPRDSTR table, then joined with IMITMFIL to the retrieve the component information. This resulted in faster performance.

The key for faster join performance is to narrow down the data to a subset first before performing the inner join.

EMK

Feedback and Knowledge Base