Если лучший индекс доступен для самого короткого потока, выбор самого большого потока в качестве управляющего потока может быть менее важным, чем экономия стоимости при выборе самого короткого потока с индексом высокой селективности (в идеале уникальный индекс). В этом случае подходящие строки в искомом потоке могут быть получены в результате одного прохода, а неподходящие строки игнорируются.
Многие графические инструменты администратора базы данных имеют средства для просмотра планов оптимизатора при подготовке оператора. Собственная утилита Firebird isql предоставляет две интерактивные команды для просмотра планов.
В интерактивной сессии isql вы можете использовать SET PLAN С необязательными ключевыми словами ON или OFF для переключения режима отображения плана в начале консольного вывода:
SQL>SET PLAN;
SQL>SELECT FIRST_NAMES, SURNAME FROM PERSON
CON>ORDER BY SURNAME;
PLAN (PERSON ORDER XA SURNAME)
FIRST NAMES
SURNAME
George Stephanie
Abraham Allen
В другой команде переключателя вы можете для isql установить отображение некоторых статистических данных запроса в конце выводимых данных, которые могут оказаться очень полезными при тестировании альтернативных структур запроса и его планов:
SQL>SET STATS ON;
SQL> запускаете ваш запрос>
PLAN..
<вывод>
Current memory = 728316
Delta memory = 61928
Max memory = 773416
Elapsed time =0.17 sec
Buffers = 2048
Reads = 15
Writes = 0
Fetches = 539
Альтернативная команда переключателя SET PLANONLY [ON | OFF] подготавливает оператор и отображает план без выполнения запроса:
SQL>SET PLAN OFF;
SQL>SET PLANONLY ON;
SQL>SELECT FIRST_NAMES, SURNAME FROM PERSON
CON>ORDER BY SURNAME;
PLAN (PERSON ORDER XA_SURNAME)
Если вы собираетесь использовать план оптимизатора в качестве стартовой точки для конструирования пользовательского предложения PLAN, то имейте в виду, что синтаксис выводимого выражения идентичен требуемому синтаксису для выражения плана в операторе[80]. Неудобным является то, что в isql не существует возможности выводить план оптимизатора в текстовый файл.
! ! !
СОВЕТ. Графические инструменты, которые отображают планы, обычно предоставляют средства копирования/вставки.
. ! .
Следующие примеры используют запросы, которые вы сами можете проверить, используя тестовую базу данных employee.fdb, инсталлированную в ваш каталог примеров[81].
Этот запрос просто отыскивает все строки из таблицы соответствия в произвольном порядке. Хотя оптимизатор определяет наличие индекса (индекс первичного ключа), он его не использует для поиска:
SQL>SET PLANONLY ON;
SQL> SELECT * FROM COUNTRY;
PLAN (COUNTRY NATURAL)
Это все еще простой запрос без соединений:
SQL>SELECT * FROM COUNTRY ORDER BY COUNTRY;
PLAN (COUNTRY ORDER RDB$PRIMARYl)
Оптимизатор выбирает индекс первичного ключа, потому что он имеет запрашиваемое упорядочение; при этом не требуется создание промежуточного потока для сортировки.
Теперь давайте посмотрим, что произойдет, когда мы решим упорядочить тот же самый запрос по неиндексированному столбцу:
SELECT * FROM COUNTRY ORDER BY CURRENCY;
PLAN SORT ((COUNTRY NATURAL))
Оптимизатор выбирает выполнение сортировки, просматривая таблицу COUNTRY В естественном порядке.
Перекрестное соединение, которое обычно создает бесполезный набор, вовсе не использует критериев соединения:
SQL> SELECT Е.*, P.* FROM EMPLOYEE Е, PROJECT Р;
PLAN JOIN (Р NATURAL,Е NATURAL)
Оно просто сливает каждый поток в левой части с каждым потоком правой части. Оптимизатор не использует индексы. Однако этот пример полезен в качестве введения в соединение между алиасами двух таблиц в спецификации соединения и их использовании в плане.
Алиасы, указанные в запросе, используются в плане, выводимом оптимизатором. Для совместимости при создании пользовательского плана хорошей идеей является использование того же способа идентификации таблиц, как и в запросе. При этом, несмотря на то, что синтаксический анализатор не допускает смешивания идентификаторов таблиц и их алиасов в запросах, предложение PLAN допускает любое смешивание[82]. Например, следующий вариант является приемлемым. Обратите внимание, что оптимизатор допускает использование и идентификаторов таблиц в предложении PLAN.
SQL> SELECT Е.*, P.* FROM EMPLOYEE E, PROJECT P
CON> PLAN JOIN (PROJECT NATURAL, EMPLOYEE NATURAL);
PLAN JOIN (P NATURAL, E NATURAL)
Такое соединение денормализует отношение один-ко-многим - каждый служащий имеет одну или более записей истории заработной платы:
SELECT Е.*, S.OLD_SALARY, S.NEW_SALARY
FROM EMPLOYEE E
JOIN SALARY_HISTORY S
ON S.EMP_NO = E.EMP_NO;
PLAN JOIN (S NATURAL, E INDEX (RDB$PRIMARY7))