МИНУС е наборна операция, която, освен че отнема резултатите от втората заявка от първата, също ще премахне дубликатите, ако се появят в първата група. Като такава, показаната заявка винаги ще трябва да изгради пълния набор от резултати от TABLE_1, преди да го върнете на потребителя.
Ако можете да сте сигурни, че няма дубликати за главата на trimemd/ефективната дата в първия набор (или не искате такива дубликати да бъдат премахнати), можете да опитате
SELECT RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
FROM TABLE_1 A
WHERE A.TYPE_OF_ACTION='6'
AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)
AND NOT EXISTS
(select 1 from table_2 b
where RTRIM(LTRIM(b.head)) = RTRIM(LTRIM(a.head))
and b.effective_date = a.effective_date) )
По този начин заявката може да започне да връща резултати много по-бързо, особено ако table_2 е много малка или редовете могат да бъдат достъпни чрез индекс на effect_date или head.
PS. Ако можете, премахнете битовете RTRIM(LTRIM()).
PPS. Все още няма гаранция, че ще се върне след по-малко от 8 секунди. Това ще зависи от това колко голяма е table_1 и индексите на type_of_action и/или ефективна_дата.
Добавено:
Можете да преминете с курсор през
SELECT RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
FROM TABLE_1 A
WHERE A.TYPE_OF_ACTION='6'
AND A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)
и игнорира редове, ако се върна
select 1 from table_2 b
where RTRIM(LTRIM(b.head)) = :1
and b.effective_date = :1
and rownum =1
Но със сигурност ще отнеме повече време за пълно изпълнение. Може би порядъци по-дълго (т.е. часове) в зависимост от това колко време отнема всяка проверка на table_2. Не съм сигурен точно какви критерии се използват за прекъсване (продължителност на повикване или продължителност на отворен SQL курсор), така че може да затвори външния курсор. И в зависимост от размера/индекса/съдържанието на table_1, външният курсор все още може да не върне първите редове в рамките на времевата рамка.
Колко реда в table_1, table_2 и какви индекси са налични?