简体   繁体   中英

Optimal Advantage SQL sub-query

I'm trying to optimize an SQL query for an Advantage 11 database. In short, I'm trying to build a query to calculate the total number of steps in a manufacturing sequence and the number of those that have been completed. The system supports multiple "releases" per job and multiple sub-assemblies per release. There are several tables that contain various values needed for the query. I have a query that works but it is way to slow to be of programmatic use. The database tables involved are:

inproces (releases that are in process)
H-JOB#         HPROC-SEQ
ABC-0100-001   101
ABC-0100-002   101
DEF-0100-001   205
ABC-0100-001P1 302

release  (main release information, including release status)
R-JOB#     R-TRACKING-NBR    R-RELEASE-STATUS
ABC-0100   ABC-0100-001      Y
ABC-0100   ABC-0100-002      Y
DEF-0100   DEF-0100-001      Y
GHI-0100   GHI-0100-002      N

pnlrel   (sub-assembly release information, including release status)
P-JOB-NBR  P-TRACKING-NBR    P-RELEASED-FLAG
ABC-0100   ABC-0100-001P01   Y
DEF-0100   DEF-0100-001P01   Y
GHI-0100   GHI-0100-002P01   N

travdet  (process steps per job, per sequence)
Job-#          Process-Sequence   Gate ID    
ABC-0100-001   101                IS  
ABC-0100-001   101                DR
ABC-0100-001   101                PL
ABC-0100-001   101                SM
ABC-0100-001   101                GN
ABC-0100-001   103                IS  
ABC-0100-001   103                DR
ABC-0100-001   103                PL
ABC-0100-001   103                SM
ABC-0100-002   101                IS  
ABC-0100-002   101                DR
ABC-0100-002   101                PL
ABC-0100-002   101                SK
DEF-0100-001   205                AB
DEF-0100-001   205                CD
DEF-0100-001   205                EF
DEF-0100-001   205                GH
DEF-0100-001   205                IJ
DEF-0100-001   212                AB
DEF-0100-001   212                CD
DEF-0100-001   212                EF
DEF-0100-001   212                GH
DEF-0100-001   212                IJ
ABC-0100-001P1 302                QR
ABC-0100-001P1 302                ST
ABC-0100-001P1 302                UV
ABC-0100-001P1 302                WX
ABC-0100-001P1 302                YZ
ABC-0100-001P1 309                QR
ABC-0100-001P1 309                ST
ABC-0100-001P1 309                UV
ABC-0100-001P1 309                WX
ABC-0100-001P1 309                YZ

detail   (process steps completed per release)
D-JOB#         D-DEST
ABC-0100-001   IS  
ABC-0100-001   DR
ABC-0100-001   PL
DEF-0100-001   AB
DEF-0100-001   CD
DEF-0100-001   EF
DEF-0100-001   GH
ABC-0100-001P1 QR
ABC-0100-001P1 ST
ABC-0100-001P1 UV
ABC-0100-001P1 WX
ABC-0100-001P1 SK

history  (current process step)
S-JOB#      S-GATE  
ABC-0100-001   IJ
ABC-0100-002   SK
DEF-0100-001   GH
ABC-0100-001P1 SK

So for every record in "inproces":

  • Determine if the release is actually released (and not cancelled) by verifying release.R-RELEASE-STATUS = Y (for main releases) or pnlrel.P-RELEASED-FLAG = Y (for sub-assemblies). I unioned two queries together to cover both of these criteria as a release will be in either the release OR pnlrel table, but not both.

  • Verify process step "SK", which would indicate it has been moved to stock.

  • Ultimately if those qualification are met I need to count the number of process steps in the matching process sequence from travdet and the number of completed process steps from detail.

The query I'm using:

select inproces."H-JOB#" as job, count(distinct travdet."GATE ID") as ttl , count(distinct detail."D-DEST") as comp
from inproces 
left join release on inproces."H-JOB#" = release."R-TRACKING-NBR"
left join travdet on release."R-JOB#" = travdet."JOB-#" and inproces."H-PROC-SEQ" = travdet."Process-Sequence" 
left join detail on detail."D-JOB#" = inproces."H-JOB#" and detail."D-DEST" <> ''
left join history on inproces."H-JOB#" = history."S-JOB#" and history."S-GATE" <> 'SK'
where release."R-RELEASE-STATUS" = 'Y' 
group by job
union
select inproces."H-JOB#" as job, count(distinct travdet."GATE ID")as ttl, count(distinct detail."D-DEST") as comp
from inproces 
left join pnlrel on inproces."H-JOB#" = pnlrel."P-TRACKING-NBR"
left join travdet on pnlrel."P-JOB-NBR" = travdet."JOB-#" and inproces."H-PROC-SEQ" = travdet."Process-Sequence"
left join detail on detail."D-JOB#" = inproces."H-JOB#" and detail."D-DEST" <> ''
left join history on inproces."H-JOB#" = history."S-JOB#" and history."S-GATE" <> 'SK'
where pnlrel."P-RELEASED-FLAG" = 'Y' 
group by job

The output (for data from sample tables):

job             ttl    comp
ABC-0100-001    5      3 
DEF-0100-001    10     4   

Note that ABC-0100-002 and ABC-0100-001P1 are excluded because their GATE ID = "SK".

I would really appreciate any advice on how to improve the performance of this query!

One of the common problems with slow performing query is lack of index for optimization. The lazy solution is to make sure that every column used in the joins is covered by an index. Alternatively, use the execution plan in the Advantage Data Architect to see potential cause of the problem and suggested solutions.

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