1

I'm having a problem that I really don't understand. I have a SQL query that takes about 3 s to compute and returns a table with 2500 lines. If I try to narrow the results with any of the following simple conditions

column_something IS NOT NULL
column_something = 'string_a'
column_something BETWEEN 'string_a' AND 'string_c'

the query becomes much slower (more than 10 min, sometimes) to return 100 lines, or so. Does anyone have an explanation for this?

In my company, we use a software where every action is performed through a GUI and the information is stored on an Oracle DB. We’re only able to access de DB to retrieve information using SQL SELECTs.
The query is the following:

1   SELECT              
2       mpno,           
3       mp_rev,         
4       taskcardno,         
5       task_rev,           
6       docno,          
7       doc_type,           
8       doc_rev,            
9       ac_registr,         
10      pre_post            
11  FROM                
12      (SELECT         
13          DOC.mpno,       
14          DOC.mp_rev,     
15          DOC.taskcardno,     
16          DOC. task_rev,      
17          DOC.docno,      
18          DOC.doc_type,       
19          DOC.doc_rev,        
20          TC.ac_registr,      
21          MAX(CASE        
22              WHEN (SELECT P.amount_int FROM parameters P WHERE P.parameter = '1428') =  0 THEN   
23                  CASE
24                      WHEN TC.event_status IN ('O', 'A', 'B', 'J') THEN 'PRE'
25                      WHEN TC.event_status IN ('F', 'T', 'V', 'C') THEN  'POST'
26                  END
27              ELSE    
28                  CASE
29                      WHEN TC.event_status IN ('O', 'A', 'B', 'J', 'N', 'E', 'I', 'Y', 'R') THEN 'PRE'
30                      WHEN TC.event_status IN ('F', 'T', 'V', 'C') THEN  'POST'
31                  END
32          END) pre_post       
33      FROM            
34          (SELECT     
35              DH.docno,   
36              DH.doc_type,    
37              DH.revision doc_rev,    
38              DH.docno_i, 
39              TC.mpno,    
40              TC.mp_rev,  
41              TC.taskcardno,  
42              TC.taskcard_verno_i,    
43              TC.task_rev 
44          FROM        
45              doc_header DH   
46              JOIN    
47              (SELECT DISTINCT    
48                  DH.docno,
49                  DH.doc_type,
50                  MMP.mpno,
51                  MMR.revision_no mp_rev,
52                  MT.taskcardno,
53                  MTV.taskcard_verno_i,
54                  MTV.revision_no task_rev
55              FROM    
56                  msc_maintenance_program MMP
57                  JOIN msc_taskcard MT ON MMP.mpno_i = MT.mpno_i 
58                  JOIN msc_taskcard_version MTV ON MT.taskcardno_i = MTV.taskcardno_i 
59                  JOIN msc_mprev_taskcards MMT ON MTV.taskcard_verno_i = MMT.taskcard_verno_i 
60                  JOIN msc_mp_revision MMR ON MMT.revisionno_i = MMR.revisionno_i 
61                  JOIN msc_item MI ON MTV.taskcard_verno_i = MI.taskcard_verno_i
62                  JOIN msc_taskcard_version MTV ON MT.taskcardno_i = MTV.taskcardno_i 
63                  JOIN msc_item MI ON MTV.taskcard_verno_i = MI.taskcard_verno_i
64                  JOIN event_effectivity_link EEL ON MI.itemno_i = EEL.event_key AND EEL.event_type = 'TI'
65                  JOIN db_link DB ON EEL.effectivity_linkno_i = DB.source_pk AND DB.source_type = 'EFL' AND DB.destination_type = 'DO'
66                  JOIN doc_header DH ON DB.destination_key = DH.docno_i AND DH.release_state <> 'I'
67              ) TC ON DH.docno = TC.docno AND DH.doc_type = TC.doc_type   
68          WHERE       
69              DH.release_state <>'I'  
70          ) DOC       
71          LEFT JOIN       
72          (SELECT     
73              MTV.taskcard_verno_i,   
74              DH.docno_i, 
75              WH.ac_registr,  
76              WEL.event_status    
77          FROM        
78              msc_maintenance_program MMP 
79              JOIN msc_taskcard MT ON MMP.mpno_i = MT.mpno_i  
80              JOIN msc_taskcard_version MTV ON MT.taskcardno_i = MTV.taskcardno_i     
81              JOIN msc_mprev_taskcards MMT ON MTV.taskcard_verno_i = MMT.taskcard_verno_i     
82              JOIN msc_mp_revision MMR ON MMT.revisionno_i = MMR.revisionno_i     
83              JOIN msc_item MI ON MTV.taskcard_verno_i = MI.taskcard_verno_i  
84              JOIN event_effectivity_link EEL1 ON MI.itemno_i = EEL1.event_key AND EEL1.event_type = 'TI' 
85              JOIN applicability A ON EEL1.effectivityno_i = A.effectivityno_i AND A.ref_type = 'AC_INT'  
86              JOIN aircraft AC ON A.ref_key = AC.aircraftno_i     
87              JOIN db_link DB ON EEL1.effectivity_linkno_i = DB.source_pk AND DB.source_type = 'EFL' AND DB.destination_type = 'DO'   
88              JOIN doc_header DH ON DB.destination_key = DH.docno_i AND DH.release_state <> 'I'   
89              LEFT JOIN doc_replacement DR ON DH.docno_i = DR.docno_i AND DR.replacement_code IN ('SB', 'CB') 
90              LEFT JOIN doc_signoff_tree DST ON DH.docno_i = DST.ref_docno_i OR DR.ref_docno_i = DST.ref_docno_i OR DH.docno_i = DST.docno_i OR DR.ref_docno_i = DST.docno_i  
91              LEFT JOIN event_effectivity_link EEL2 ON (DST.docno_i = EEL2.event_key OR DST.ref_docno_i = EEL2.event_key) AND EEL2.event_type = 'DO'  
92              LEFT JOIN wo_event_link WEL ON EEL2.event_key = WEL.event_key_parent AND WEL.event_type = 'DOC_EFF' AND WEL.pending_status = 0  
93              LEFT JOIN wo_header WH ON WEL.event_perfno_i = WH.event_perfno_i AND WH.ac_registr = AC.ac_registr  
94          WHERE       
95              WEL.event_status IS NOT NULL    
96          ) TC ON (DOC.docno_i = TC.docno_i AND DOC.taskcard_verno_i = TC.taskcard_verno_i)       
97      GROUP BY            
98          DOC.mpno,       
99          DOC.mp_rev,     
100         DOC.taskcardno,     
101         DOC. task_rev,      
102         DOC.docno,      
103         DOC.doc_type,       
104         DOC.doc_rev,        
105         TC.ac_registr       
106     )           
107 WHERE               
108     ac_registr = 'TPO'

If I run lines 1 to 106, it returns the 2500 lines after 3s as I mentioned.
If I add lines 107 and 108, it takes around 10 min to return 100 lines.
ac_registr is indexed as well as every column used on JOINs.
I know this is quite specific and finding help would be a long shot, but being a self-taught noob I was looking for a general explanation of the rationale behind this, because I just don’t get it.
Thank you.

HLGEM
  • 94,695
  • 15
  • 113
  • 186
Fimicaso
  • 27
  • 2
  • 4
    Did you create an index for column `column_something ` ? But if your table only have 2500 lines, maybe the problem is you have a very busy server or slow disk – Juan Carlos Oropeza Aug 09 '17 at 14:40
  • 1
    are you "narrowing" the results by doing .... `OR` column_something is not null... ? Does your query have any outer joins? I understand your confusion as one would expect the query to get the 2500 lines in 3 sec and then limit it further taking just a second more to process the 2500 lines. but w/o seeing execution plan and knowing table stats, help on improving performance is not really possible. We are all just guessing. – xQbert Aug 09 '17 at 14:41
  • 1
    You should show us the whole query. Because is very unlike than a query for a 2500 rows table take 10 min, even without index. – Juan Carlos Oropeza Aug 09 '17 at 14:43
  • 1
    The query will take more or less time based on the number of rows has to read and how many times, not in how many rows gives in the answer, so it can give you an answer of 100 rows but has to read thousands of rows – nacho Aug 09 '17 at 14:43
  • 2
    Performance questions should include `EXPLAIN ANALYZE` and some information about table size, index, current time performance, desire time, etc. `Slow` is a relative term and we need a real value to compare. [**MySQL**](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) [**How do I obtain a Query Execution Plan?**](http://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan) – Juan Carlos Oropeza Aug 09 '17 at 14:44
  • 2
    And you should tag your question with the database you are using. – Gordon Linoff Aug 09 '17 at 15:11
  • Thank you for the quick feedback! I tried to provide more information – Fimicaso Aug 10 '17 at 14:52
  • http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN, You may not even be getting correct results with the current query. – HLGEM Aug 10 '17 at 15:19

0 Answers0