Применение distinct
Помимо своего прямого назначения - выборку уникальных значений , оператор distinct имеет 2 побочные,
но очень полезные свойства.
Во первых, используя distinct в подзапросе, во многих случаях мы
можем заставить Oracle воспринимать подзапрос как представление, т.е. в плане
выполнения запроса появляется VIEW и, соответственно, в общем запросе будут принимать
участие только отобранные в подзапросе строки. Это хорошо видно на этом примере.
Во вторых, при применении distinct происходит и сортировка, причём более быстрая, чем используя ORDER BY .
Рассмотрим простой пример:
SELECT client_code, name FROM client ORDER BY client_code

В данном запросе намеренно взято за основу поле без индекса, именно в этом случае и видно преимущество distinct
(для таких простых запросов). Вариант с distinct:
SELECT DISTINCT(client_code), name FROM client

Как видим, преимущество есть. Но!
Подобный вид сортировки можно применять только для полей с уникальными значениями.
Для более сложных запросов с многими таблицами, такой способ сортировки зачастую становится единственно приемлемым:
select /*+ RULE */ s.subacc, c.char_code,
substr(nvl(s.name,si.name||' '||cl.name),1,38) name,
s.id_subacc, s.id_kind, isu.id_client,0 TypeDiv
from Subacc s ,Currency c, Client cl,
Subacc_mapping sm, Subacc_item si, Isubacc isu
where s.id_item=si.id_item(+)
and sm.id_subacc = s.id_subacc
and sm.id_list_acc = 2
and sm.id_isubacc = isu.id_isubacc
and cl.id_client=isu.id_client
and isu.id_cur = c.id_cur
and not exists ( select 1 from isubacc_group igr
where igr.id_isubacc = isu.id_isubacc
and igr.id_isub_group = 1 )
order by subacc
Запрос достаточно сложный для оптимизации, выполняется 2 сек, выдаёт "на гора" 14 тыс записей, и основным
тормозом тут являеся order by subacc. Без него запрос выполняется ~0,4 сек.
Теперь вариант на основе distinct ( без ORDER BY ).
SELECT /*+ RULE */ s.subacc, c.char_code,
SUBSTR(NVL(s.name,si.name||' '||cl.name),1,38) name,
s.id_subacc, s.id_kind, isu.id_client,0 TypeDiv
FROM Currency c, Client cl, Subacc_mapping sm, Subacc_item si, Isubacc isu,
(SELECT DISTINCT(subacc),name,id_subacc,id_kind, id_item FROM Subacc) s
WHERE s.id_item=si.id_item(+)
AND sm.id_subacc = s.id_subacc
AND sm.id_list_acc = 2
AND sm.id_isubacc = isu.id_isubacc
AND cl.id_client=isu.id_client
AND isu.id_cur = c.id_cur
AND NOT EXISTS ( SELECT 1 FROM isubacc_group igr
WHERE igr.id_isubacc = isu.id_isubacc
AND igr.id_isub_group = 1 )
Запрос выполняется 0,35 сек. Выполнение запроса строится на основе отсортированной
изначально во VIEW таблице SUBACC , поэтому и результирующий набор также получается сортированным:

перевоначальный запрос:
