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

SELECT p.name, pt.name, d e s c r ip t io n , p r ice

FROM products p, product_types pt

WHERE p.product_type_id = pt .produc t_type_id

AND p.product_id = 1;

NAME NAME

DESCRIPTION PRICE

Modern Science Book

A d e s c r ip t io n of modern sc ience 19.95

Этот пример работает, но базе данных приходится искать столбцы

description и price в обеих таблицах - products и product_types. Дело в том,

что для этих столбцов отсутствуют псевдонимы, подсказывающие базе

данных, какой таблице принадлежит каждый из этих столбцов. Время,

потраченное базой данных на такой поиск, - это потерянное время.

В следующий пример включен псевдоним р таблицы products, чтобы

можно было полностью определить столбцы description и price.

□ __ ХОРОШИЙ ВАРИАНТ (полностью определённые столбцы)

SELECT p.name, pt.name, p .d e s c r ip t io n , p .p r ic e

Настройка высокой производительности SQL 601

FROM products р, product_types pt

WHERE p.product_type_id = pt.product_type_id

AND p.product_id = 1;

NAME NAME

DESCRIPTION PRICE

Modern Science Book

A description of modern science 19.95

Поскольку все ссылки на столбцы в этом запросе полностью определены

(в них включены псевдонимы таблиц), база данных не будет терять время

на поиск, в каких таблицах содержатся эти столбцы, и время выполнения

запроса сократится.

Используйте выражения CASE, а не несколько запросов

Когда нужно выполнить много вычислений над одной и той же строкой

таблицы, лучше использовать выражение CASE, чем несколько запросов.

В следующем примере йспользуется несколько запросов для подсчета числа

товаров в различных ценовых интервалах (плохой вариант):

□ — ПЛОХОЙ ВАРИАНТ (три отдельных запроса, хотя мог работать один оператор

CASE)

SELECT C0UNT(*)

FROM products

WHERE p r ic e < 13;

COUNT(* )

2

SELECT C0UNT(*)

FROM products

WHERE price BETWEEN 13 AND 15;

C0UNT(*)

5

SELECT C0UNT(*)

FROM products

WHERE price > 15;

C0UNT(*)

5

Вместо того чтобы использовать три отдельных запроса, как было только

что показано, нужно было написать один запрос, в котором используются

выражения CASE:

602 Глава 16

□ __ ХОРОШИЙ ВАРИАНТ (один запрос с выражением CASE вместо трех запросов)

SELECT

COUNT(CASE WHEN p r ic e < 13 THEN 1 ELSE n u l l END) low,

COUNT(CASE WHEN p r ic e BETWEEN 13 AND 15 THEN 1 ELSE n u l l END) med,

COUNT(CASE WHEN p r ic e > 15 THEN 1 ELSE n u l l END) high

FROM products;

LOW MED HIGH

2 5 5

Счетчик товаров с ценой ниже 13 долларов помечен как low, счетчик

товаров с ценой от 13 до 15 долларов обозначен med, а счетчик товаров,

которые дороже 15 долларов, - high.

Примечание Можно использовать в выражениях CASE перекрывающиеся интервалы и различные

функции.

Добавьте к таблицам индексы

При поиске в книге определенной темы можно либо пролистать всю книгу,

либо использовать индекс книги для прямого отыскания места, где находится

эта тема. Концепция индекса таблицы базы данных очень похожа

на концепцию индекса книги, с тем отличием, что индекс таблицы базы

данных используется для отыскания конкретной строки таблицы. «Обратной

стороной медали» при индексировании является тот факт, что при

добавлении в таблицу новой строки требуется дополнительное время на

обновление индекса для учета новой строки.

Обычно индекс по столбцу создается только в том случае, если выбирается

всего несколько строк из таблицы, содержащей большое количество

строк. Хорошим эмпирическим правилом при создании индексов является

следующее:

Создайте индекс, когда запрос будет отбирать из таблицы не более 10%

от общего числа строк в таблице.

Это значит, что в столбцах, являющихся кандидатами на создание по

ним индекса, должен храниться широкий диапазон значений. Отличным

кандидатом для индексирования мог бы стать столбец, содержащий уни

кальное число для каждой записи, а плохим кандидатом для создания индекса

будет столбец, содержащий лишь узкий диапазон числовых кодов,

например N, S, Е, W, или 1, 2, 3, 4, 5, 6. База данных Oracle автоматически

создает индекс для первичного ключа таблицы и для столбцов, включен

ных в ограничение по уникальности.

Кроме того, при выполнении иерархического запроса (т. е. запроса, содержащего

фразу CONNECT BY), нужно добавить индексы, упомянутые во

фразах START WITH и CONNECT B Y (подробнее об иерархических запросах см.

в главе 7).

Наконец, для столбца, который содержит небольшой диапазон значений

и часто используется в операторе WHERE запросов, вам следует подумать

о добавлении bitmap индекса. Bitmap индексы обычно используют в

Настройка высокой производительности SQL 603

хранилищах данных, которые представляют собой базы данных, содержащие