Наилучшим вариантом в SQL является UNION
, хотя вы можете сэкономить, выбрав ключевые слова distinct
:
select FIELD1 FROM TABLE
UNION
select FIELD2 FROM TABLE
UNION
предоставляет уникальный набор из двух таблиц, поэтому в этом случае отдельный является избыточным. Просто нет способа написать этот запрос иначе, чтобы он работал быстрее. Там нет волшебной формулы, которая делает поиск более 200 000 строк быстрее. Он должен искать каждую строку таблицы дважды и сортировать по уникальности, что и делает UNION
.
Единственный способ сделать это быстрее - это создать отдельные индексы для двух полей (возможно) или сократить набор данных, по которым вы ведете поиск.
В качестве альтернативы, если вы делаете это много и редко добавляете новые поля, вы можете использовать материализованное представление для сохранения результата и обновлять его только периодически.
Кстати, ваш второй запрос, похоже, не выполняет то, что вы хотите. Distinct
всегда применяется ко всем столбцам в разделе select
, поэтому ваши константы с именами полей будут приводить к тому, что запрос всегда будет возвращать отдельные строки для двух столбцов.
Я придумала другой метод, который экспериментально кажется немного быстрее. В действительности это позволяет нам обменять одно сканирование полной таблицы на декартово объединение. В большинстве случаев я все же решил бы использовать union
, поскольку гораздо более очевидно, что делает запрос.
SELECT DISTINCT CASE lvl WHEN 1 THEN field1 ELSE field2 END
FROM table
CROSS JOIN (SELECT LEVEL lvl
FROM DUAL
CONNECT BY LEVEL <= 2);
Также стоит добавить, что я протестировал оба запроса в таблице без полезных индексов, содержащих 800 000 строк, и это заняло примерно 45 секунд (возвращая 145 000 строк). Однако большую часть этого времени было потрачено на выборку записей, а не на выполнение запроса (запрос занял 3-7 секунд). Если вы получаете значительное количество строк назад, это может быть просто количество строк, которое вызывает проблему с производительностью, которую вы видите.