Шрифт:
Этот синтаксис позволяет задавать одно отношение или соединение двух или более отношений за один раз. Могут быть использованы вложенные скобки для задания любых комбинаций соединений. Операции передают свои результаты в выражении слева направо.
В используемой здесь нотации круглые скобки и запятые являются элементами синтаксиса. Фигурные скобки, квадратные скобки и символ вертикальной черты не являются частью синтаксиса- как и в ранее описанном синтаксисе они указывают, соответственно, обязательные и необязательные фразы и взаимоисключающие варианты.
plan-expression := [join-type] (plan-item-list)
join-type := [JOIN] | [SORT] [MERGE]
plan-item-list := plan-item | plan-item, plan-item-list
plan-item := table-identifier access-type | plan_expression
table-identifier := { table-identifier | alias-name } [table-identifier]
access-type := { NATURAL | INDEX (index-list) | ORDER index-name }
index-list := index-name | index-name, index-list
Тип соединения (join-type) может быть JOIN или MERGE.
* Тип соединения по умолчанию JOIN (т. е. соединение двух потоков с использованием индекса правого потока для поиска соответствующих ключей в левом потоке).
* MERGE выбирается, если нет используемых индексов. В этом случае два потока сохраняются в соответствующем порядке, а затем сливаются. В пользовательских планах скорость поиска будет увеличена при задании такого типа соединения, когда нет доступных индексов.
Идентификатор таблицы (table-identifier) задает поток. Он должен быть именем таблицы базы данных или алиасом. Если одна и та же таблица будет использована более одного раза, для нее должен быть указан алиас для каждого использования. Алиас должен следовать после имени таблицы при ее первом упоминании. Для спецификации базовых таблиц в просмотре синтаксис предоставляет возможность давать таблицам множество идентификаторов. Планы для просмотров обсуждаются в главе 24.
Тип доступа (access-type) должен быть одним из следующих:
* NATURAL - доступ к строкам осуществляется последовательно, без какого-либо особого порядка. Это тип доступа по умолчанию, он может быть опущен, тем не менее разумно включить его в пользовательский план для документирования;
* INDEX - позволяет указать один или более индексов для вычисления предикатов и проверки условий соединения в запросе;
* ORDER- указывает, что результат запроса должен быть отсортирован (упорядочен) по самому левому потоку с использованием индекса.
Элемент плана (plan-item) включает в себя план доступа, а также идентификатор таблицы или ее алиас.
Если вы не очень хорошо знакомы с планами запросов, вы, вероятно, будете удивлены, как весь этот синтаксис может транслироваться в план. Чуть позже синтаксис станет более осмысленным, когда мы посмотрим на некоторые планы, сгенерированные оптимизатором. Тем не менее в настоящий момент будет полезным посмотреть, как оптимизатор использует "материал" для его операций: соединения и условия поиска, требуемые в операторе, потоки, лежащие в основе спецификации запроса, и доступные индексы.
Цель оптимизатора - создать отражающий стратегию план, который, в соответствии с некоторыми факторами, скорее всего, начнет выдавать выходной поток наиболее быстрым образом. Вычисление плана может оказаться довольно неточным при использовании некоторых переменных, которые могут дать только приблизительную оценку. Рассматриваемые факторы включают:
* доступность индекса и селективность этого индекса. Фактор селективности, используемый в оценках, выбирается из системных таблиц при открытии базы данных. Даже в начале работы он может быть неверным, поскольку может изменяться в процессе операций обширных изменений, выполненных с момента последнего вычисления селективности;
* количество строк в таблицах потоков;
* существует ли критерий выбора, и если да, существует ли доступный или подходящий индекс;
* необходимость выполнения сортировок, как промежуточных (для слияния), так и окончательной (для упорядочения и группирования).
Применение термина "поток", который возникает при обсуждении оптимизатора, является просто общим способом наименования множества строк. Набор может содержать все строки и столбцы таблицы или это может быть подмножество данных таблицы, ограниченное некоторым образом спецификациями столбцов и условиями поиска. В процессе обработки запроса сервер может из существующего потока создавать новые потоки, такие как внутренний сортированный набор или набор значений подзапроса для сравнения IN. См. также далее разд. "Реки".
Сервер Firebird может использовать в запросах индекс для трех видов задач.
* Сравнение: выполняется сравнение на условия равно, больше, меньше или STARTING WITH между значением столбца и константой. Если столбец индексирован, то индексный ключ используется для сокращения просматриваемых строк, делая ненужным сканирование всех строк таблицы данных.
* Соответствие потоков для соединений: если доступен индекс для столбцов, указанных в качестве условия соединения для потока с одной стороны соединения, то поток другой стороны будет отыскиваться первым, а его столбцы соединения будут проверяться на соответствие с помощью индекса.