Использование планов запросов для просмотров
Использование планов запросов для просмотров
Просмотры могут представлять для пользователей некоторые сложности относительно возможности PLAN. В основном пользователи могут трактовать просмотры как обычные таблицы. Однако, если вы захотите определить пользовательский план, вам нужно иметь сведения об индексах и структурах базовых таблиц, участвующих в просмотре.
Оптимизатор трактует ссылку на просмотр так, как если бы базовые таблицы, используемые при создании просмотра, были добавлены в список FROM запроса.
Предположим, просмотр был создан следующим образом:
CREATE VIEW V_PROJ_LEADERS (
PROJ_ID,
PROJ_TITLE,
LEADER_ID,
LEADER_NAME)
AS
SELECT
P.PROJ_ID,
P. PROJ_NAME,
P. TEAM_LEADER,
E.FULL_NAME,
FROM PROJECT P
JOIN EMPLOYEE E
ON P.TEAM_LEADER = E.EMPNO;
Простой запрос к просмотру
SELECT * FROM V_PROJ_LEADERS;
выводит следующий план:
PLAN JOIN (V_PROJ_LEADERS P NATURAL, V_PROJ_LEADERS E INDEX (RDB$PRIMARY7) )
Обратите внимание, что оптимизатор обращается к индексам базовых таблиц (через алиасы р и Е) для лучшего способа поиска в просмотре. Спецификация SELECT в объявлении CREATE VIEW определяет логику выполнения соединения.
Следующий запрос является чуть более сложным. В этот раз просмотр соединяется с таблицей EMPLOYEE PROJECT с помощью первичных ключей таблиц EMPLOYEE и PROJECT. Затем он опять соединяется с таблицей EMPLOYEE для получения ненормализованного списка, который включает имена участников всех проектов, управляемых просмотром:
SELECT
PL.*,
EMP.LAST_NAME
FROM V_PROJ_LEADERS PL
JOIN EKPLOYEE_PROJECT EP
ON PL.PROJ_ID = EP.PROJ_ID
JOIN EMPLOYEE EMP
ON EP.EMP_NO = EMP.EMP_NO;
PLAN JOIN (EMP NATURAL, EP INDEX (RDB$FOREIGN15) , PL P INDEX (RDB$PRIMARY12) ,
PL E INDEX (RDB$PRIMARY?) )
В этот раз индекс внешнего ключа для столбца EMP_NO таблицы EMPLOYEE_PROJECT (с алиасом EP) используется для выбора имен участников проекта из второго "элемента" - EMPLOYEE. Как и в предыдущем случае, соединение внутри просмотра использует первичный ключ таблицы EMPLOYEE для поиска соответствия в TEAM_LEADER.
Если вы решите написать свой план для запроса, который работает с просмотром, вам нужно хорошо знать определение просмотра, понимать индексы и методы доступа.
Известная ошибка в просмотрах в Firebird 1.0.x
Если вы определяете просмотр, который является объединением (union) двух или более наборов, просмотр будет вести себя неправильно при использовании в подзапросе в Firebird 1.0.x. Например, следующий запрос приведет к краху сервера:
SELECT 1 FROM Table1 WHERE EXISTS (
SELECT FIELD1 FROM UNION_VIEW WHERE <условия-поиска> )
Эта ошибка была исправлена до релиза версии 1.5.