Шрифт:
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 не существует возможности выводить план оптимизатора в текстовый файл.
! ! !
СОВЕТ. Графические инструменты, которые отображают планы, обычно предоставляют средства копирования/вставки.
80
Многие аспекты плана, сконструированного внутренне оптимизатором, не видны в плане, показанном в isql и недоступны через синтаксис предложения PLAN для пользовательских планов. Синтаксис показывает только подмножество реального плана, которому будет следовать сервер при выполнении запроса.
. ! .
Следующие примеры используют запросы, которые вы сами можете проверить, используя тестовую базу данных employee.fdb, инсталлированную в ваш каталог примеров [81] .
Этот запрос просто отыскивает все строки из таблицы соответствия в произвольном порядке. Хотя оптимизатор определяет наличие индекса (индекс первичного ключа), он его не использует для поиска:
SQL>SET PLANONLY ON;
81
Поскольку база данных примера не имеет таблиц без индексов, некоторые примеры в этом разделе используют специально описанные неиндексированные версии таблиц EMPLOYEE, PROJECT и DEPARTMENT, названные EMPLOYEE1, PROJECT1 и Departments соответственно. Скрипт с именем NO_INDEXES.SQL для создания этих таблиц может быт загружен с http://www.apress.com.
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.
82
Другой причиной использования алиасов при задании запросов и планов является то, что, скорее всего, подобная согласованность будет поддерживаться в следующих версиях Firebird.
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