Есть две таблицы A и B (достаточно большие 100-200 тысяч записей в каждой). Очень тормозит вот такой запрос:
select *
from A left join B on (A.Id = b.RefA)
where (A.DocNumber = 128) or (B.DocNumber = 128)
<план>
FILTER
HASH JOIN
FULL SCAN A
FULL SCAN B
A.Id - первичый ключ в таблице A, b.RefA - ссылка на A (проиндексирована). Oracle пытается вначале приджойнить таблицы причем не по индексу а HASH JOIN, а потом их фильтровать.
А вот такой запрос не тормозит (т.к. там сперва проверка условий, а потом join по индексу)
select *
from A left join B on (A.Id = b.RefA)
where (A.DocNumber = 128)
union
select *
from A left join B on (A.Id = b.RefA)
where (B.DocNumber = 128)
<план>
UNIQUE SORT
UNION ALL
LOOP OUTER
FULL SCAN A
объединение с B по индексу
LOOP
FULL SCAN B
объединение с A по индексу
Насколько я понимаю эти запросы эквивалентны. Кто-нибудь знает в чем тут может быть дело? (Oracle вроде умеет преобразовывать запросы с or к union, только вот почему-то делает он это только при inner join, а при left не делает, но в данном случае left join принципиален и его нелзя заменнить на inner).
Версия Oracle 9.2.0.4, 10.2.0.1. Писать (+)= пробовал - не помогает. Наличие или отсутствие индексов на полях DocNumber на сокорость работы существенного влияния не оказывают. Кстати условие ограничения довольно сильное, т.к. в результате получается всего около 100-200 записей.