бы использовать EXISTS) для выборки проданных товаров:
□ — ПЛОХОЙ ВАРИАНТ (использует IN вместо EXISTS)
SELECT product_id, name
FROM products
WHERE product_id IN
(SELECT product_id
FROM purchases);
PRODUCT_ID NAME
1 Modern Science
2 Chemistry
3 Supenova
606 Глава 16
Следующий запрос переписывает этот пример, чтобы в нем использовалась
фраза EXISTS:
П — ХОРОШИЙ ВАРИАНТ (использует EXISTS, а не IN)
SELECT product_id, паше
FROM products outer
WHERE EXISTS
(SELECT 1
FROM purchases inner
WHERE inner. product_id = outer. product_id);
PRODUCT_ID NAME
1 Modern Science
2 Chemistry
3 Supenova
Используйте EXISTS, а не DISTINCT
Используя ключевое слово DISTINCT, можно подавить вывод повторяющихся
строк; EXISTS используется для проверки существования строк, возвращенных
подзапросом. Там, где возможно, следует вместо DISTINCT использовать
EXISTS, потому что DISTINCT сортирует отобранные строки, прежде
чем подавить вывод повторяющихся строк.
Следующий запрос использует для выборки проданных товаров DISTIN СТ
(плохой вариант, так как должно работать ключевое слово EXISTS):
□ — ПЛОХОЙ ВАРИАНТ (использует DISTINCT, а должно работать EXISTS)
SELECT DISTINCT pr.product_id, pr.name
FROM products pr, purchases pu
WHERE pr.product_id = pu.product_id;
PRODUCT_ID NAME
1 Modern Science
2 Chemistry
3 Supernova
Следующий запрос переписывает предыдущий пример, чтобы использовать
EXISTS вместо DISTINCT:
□ — ХОРОШИЙ ВАРИАНТ (использует EXISTS, а не DISTINCT)
SELECT product_id, name
FROM products outer
WHERE EXISTS
(SELECT 1
FROM purchases inner
WHERE inner.product_id = outer.product_id);
PRODUCT_ID NAME
1 Modern Science
2 Chemistry
3 Supernova
Настройка высокой производительности SQL 607
Используйте GROUPING SETS вместо CUBE
Оператор GROUPING SETS обычно предлагает лучшую производительность
по сравнению с CUBE. Поэтому, где это возможно, следует использовать
GROUPING SETS вместо CUBE. Это полностью описано в разделе “Использование
оператора GROUPING SETS” в главе 7.
Используйте переменные связи
Программное обеспечение базы данных Oracle кэширует операторы SQL;
кэшированные операторы могут быть использованы позже, если будет задан
оператор, идентичный кэшированному. При повторном использовании
время выполнения оператора сокращается. Но здесь кроется некий
подвох: чтобы кэшированный оператор SQL мог быть повторно использован,
операторы должны совпадать полностью. Это значит, что:
■ должны совпадать все символы операторов;
■ все буквенные символы должны быть набраны в одном и том же регистре;
. -
■ должно быть одинаковым использование пробелов в обоих операторах.
Если необходимо передать в оператор различные значения столбцов,
вы можете вместо литеральных значений столбцов использовать так называемые
переменные связи (bind variables) (см. ниже).
Неидентичные операторы SQL
В этом разделе показаны некоторые неидентичные операторы SQL. В следующих
примерах выбираются товары № 1 и № 2 с помощью отдельных
неидентичных операторов:
□ SELECT * FROM products WHERE product_id = 1;
SELECT * FROM products WHERE product_id = 2;
Эти операторы неидентичные, так как в первом операторе используется
значение 1, а во втором - значение 2.
В следующем примере операторы не идентичны из-за различия в использовании
пробелов:
П SELECT * FROM products WHERE product_id = 1;
SELECT * FROM products WHERE product_id = 1;
В следующем примере причиной неидентичности является различие в
регистрах, использованных для некоторых символов:
□ SELECT * from products where product_id = 1;
SELECT * FROM products WHERE product_id = 1;
Теперь давайте посмотрим на идентичные операторы SQL, которые используют
переменные связи.
608 Глава 16
Определение идентичных операторов с использованием переменных
связи
Убедиться в идентичности операторов можно, если для представления
значений столбцов использовать переменные связи. Для создания переменных
связи используется команда VARIABLE. Следующая команда создает
переменную v_product_id типа NUMBER:
□ VARIABLE v_product_id NUMBER
Примечание___ Для определения.типа переменных связи можно использовать типы, перечисленные
в таблице А-1 приложения.______________________ ____________
На переменную связи можно ссылаться в операторе SQL и PL/SQL, используя
символ двоеточия (:), сразу за которым следует имя переменной
(например, :v_product_id). В следующем примере показан блок PL/SQL, в
котором product_type_id устанавливается на 1.
П BEGIN
:v_product_id := 1;
end;
/
В следующем примере v_product_id используется для указания значения
столбца productjd во фразе WHERE. Поскольку ранее переменная связи