Изменение порядка обработки условий
Оптимизатор изменяет порядок вычисления условий в группах SQL-запроса таким образом, чтобы минимизировать количество промежуточных записей при вычислении каждой группы условий.
Группа условий – это совокупность предикатов, соединенных операциями AND. Записи в ранее вычисленных предикатах группы будут использоваться при вычислении последующих предикатов.
Если группа содержит несколько предикатов одного ранга, то они будут обрабатываться в том порядке, в котором записаны в условии.
Оптимизатор применяет следующий порядок вычисления предикатов в группах:
-
сначала вычисляются константные предикаты.
Например,
1 = 1, (2+4) <= 5
Подобные условия формируются, в основном, при автоматическом создании SQL-запросов;
-
затем вычисляются предикаты типа
<первичный ключ>
<константа> здесь
– это одна из операций: =, LIKE или IN; -
следующими вычисляются однопеременные предикаты, в которых участвуют столбцы, не являющиеся первичными ключами и содержащие условия типа «=», LIKE или IN.
Например,
<столбец1> IN (1, 2, 3); <столбец1> LIKE '%alt';
-
далее вычисляются однопеременные предикаты (т.е. содержащие условия, отличные от «=», LIKE, IN).
Например,
B.Y <= 15; A.X between 12 and 17;
-
в последнюю очередь вычисляются многопеременные предикаты.
При этом несколько следующих друг за другом многопеременных предикатов упорядочиваются таким образом, чтобы переменные, входящие в последующий предикат, в максимальном количестве входили в предыдущие предикаты группы.
Например,
Исходная конструкция Оптимизированная конструкция ------------------------------------------------------------- <условие A.X> = B.X AND <условие A.X> = B.X AND C.Z = D.Z AND B.Y = C.Y AND B.Y = C.Y C.Z = D.Z
Из многопеременных предикатов первыми будут вычислены те, которые содержат условия типа «=», LIKE или IN, и только потом остальные.
Запрос вида
"SELECT ... FROM (SELECT ... FROM A WHERE CONDITION1 UNION ALL SELECT ... FROM B WHERE CONDITION2) WHERE CONDITION3;"
преобразуется в запрос
"SELECT ... FROM (SELECT ... FROM A WHERE CONDITION1 AND CONDITION3 UNION ALL SELECT ... FROM B WHERE CONDITION2 AND CONDITION3);"
Чтобы преобразование произошло, требуется:
-
в качестве CONDITION1, CONDITION2, CONDITION3 должны выступать предикаты и группы предикатов (CONDITION1 и CONDITION2 также могут вообще отсутствовать);
-
внутренние SELECT-запросы не должны использовать функции.
-