Всем хорошей пятницы!
Действительно ли, что:
Oracle запрос SQL, использующий условие EXISTS очень неэффективен, так как подзапрос перезапускается для каждой строки в таблице внешнего запроса.
Есть более эффективные способы написания большинства запросов, которые бы не использовали условие EXISTS.
Ответ:
Для решения каждой задачи есть свои эффективные методы. Если EXISTS применяется в основном запросе выборки из небольшой таблицы для проверки данных в большой таблице, и если выборка из большой таблицы будет вестись по индексам, то его использование будет очень эффективно. Вот пример:
В таблице клиентов не более 1000 строк.
В таблице PAYMENTS миллион строк и таблица проиндексована по столбцу CLIENT_ID.
Нужно выбрать клиентов, по которым была хотя бы одна оплата.
SELECT *
FROM CLIENTS
WHERE EXISTS (SELECT 1 FROM PAYMENTS WHERE PAYMENTS.CLIENT_ID = CLIENTS.CLIENT_ID)
По таблице CLIENTS мы видим полный перебор строк (TABLE ACCESS FULL), но с проверкой есть ли платеж по клиенту. Запрос, отбирая клиентов, проверит есть ли в таблице PAYMENTS хотя бы одна строчка с таким CLIENT_ID. Хотя бы одна. И, так как на таблицу PAYMENTS есть индекс для выборки по столбцу CLIENT_ID, то таблица PAYMENTS вообще не будет читаться! Согласно приведённому запросу нам от неё не нужны данные. Нужно просто проверить есть ли строчка, где бы в столбце CLIENT_ID было бы конкретное значение. СУБД посмотрит в индекс и сразу поймёт есть ли строчка с таким то значением CLIENT_ID. Самого чтения миллионной таблицы не будет.
Многие СУБД, при правильной их настройке, хранят индексы постоянно используемых таблиц в оперативной памяти.
Стоит, всё же, заметить, что при использовании EXISTS или других подзапросов в транзакциях в некоторых СУБД могут быть проблемы.
Расскажу об этом дополнительно!