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.