Выбрать главу

бы использовать 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. Поскольку ранее переменная связи