Применение 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 , поэтому и результирующий набор также получается сортированным:
перевоначальный запрос:
Хостинг от uCoz