Подсказка очередности слияния результатов вычисления предикатов
Функция

Управление очередностью объединения результатов вычисления предикатов.

Спецификация
   
< подсказка очередности >::=
{-- +PREDORDER=номер | /* +PREDORDER=номер */}
< номер >::=
целочисленное значение в диапазоне 1-255
Синтаксические правила
  1. Комментарий может быть:

    • строковый: исключает из выполнения только одну строку, перед которой стоят символы -- (два минуса);

    • блоковый: исключает из выполнения целый блок команд, заключенный между символами /* и */.

    select * from t1, t2, t3, t4 where
    t1.id=t2.id -- + PREDORDER = 3
    and
    t3.value=t4.value /*+PREDORDER=2*/ and
    t2.id=t3.id /*+PREDORDER=4*/ and
    t3.id=t4.id /*+PREDORDER=1*/;
Общие правила
  1. Первыми будут объединяться результаты предикатов с наименьшими номерами. Если номер у предиката не задан (например, только у части предикатов группы заданы номера с помощью подсказок), то очередность будет определяться стандартным образом, но результаты «непронумерованных» предикатов будут добавляться в выборку данных после результатов «пронумерованных».

  2. Порядок задания приоритетов должен устанавливаться экспериментальным путем.

Пример реального запроса пользователя СУБД ЛИНТЕР, который не мог быть оптимизирован без подсказок:

SELECT T_AV."Месяц" as
"Месяц","ФОТ нач.","ФОТ к выд.","$ ФОТ к выд.",
"АВАНС округл." as "Аванс", "ФОТ к выд."-"АВАНС округл." as "Ост. выдать",
"Отч. в ФКП","Отч. в ЛОФ","ФСП не менее","Ср. курс $","Сумм. ТЗ",
"Рабоч.ч.",
round ("ФОТ к выд."/"АВАНС", 2) as "Коэфф."
FROM (
select t6.mon_id as "Месяц",
ceil(sum(zp_predl_r)) as "ФОТ нач.",
ceil(sum(zp_na_ruki)) as "ФОТ к выд.",
ceil(sum(PREM_KVART)) as "Отч. в ФКП",
ceil(sum(OTPUSK)) as "Отч. в ЛОФ",
ceil(sum(zp_predl_r)*3.0/97.0) as "ФСП не менее",
ceil(sum(zp_na_ruki)/avg(SR_KURS_DOLL)) as "$ ФОТ к выд.",
round(avg(SR_KURS_DOLL),2) as "Ср. курс $"
from svodn, tab6_time as t6
WHERE
svodn.mon_id=t6.mon_id
group by t6.mon_id ) as T_OTCH,
           /*order by t6.mon_id desc;*/
 (select mon_ID as "Месяц", sum("АВАНС округл.") as "АВАНС округл.",
sum("Сумм. ТЗ") as "Сумм. ТЗ", sum("Рабоч.ч.") as "Рабоч.ч." ,
sum("АВАНС") as "АВАНС"
from
(
select t1.MON_ID,
t6."WH" as "Рабоч.ч.", t4."S_MIN_TZ" as "Сумм. ТЗ",
(t2.DO+t1.MLN)*(t4."S_MIN_TZ"/t6."WH")*(0.9-1.0/12.0) as "АВАНС",
floor(
(t2.DO+t1.MLN)*(t4."S_MIN_TZ"/t6."WH")*(0.9-1.0/12.0)/50.0
)*50 as "АВАНС округл."
from TAB1_USERS as t0, TAB1_USERS_INCR as t1, TAB2_DOL_INCR as t2,
(select mon_id, user_id, sum(MIN_TZ) as "S_MIN_TZ"
     from   SVODN, PR_DATA
      where (  SVODN.PR_ID=PR_DATA.PR_ID)  and (PR_DATA.PR_NAME not like
'%-Бонус%')  and (PR_DATA.PR_NAME not like '%-бонус%')
  group by mon_id, user_id) as t4,
TAB6_TIME as t6
where

/*  вариант без подсказок – оптимизация не выполняется */
                                    /*
t1.MON_ID=t2.MON_ID and
t1.DOL_ID=t2.DOL_ID and
t0.USER_ID=t1.USER_ID and
t1.MON_ID=t4.MON_ID and t0.USER_ID=t4.USER_ID
and t1.MON_ID=t6.MON_ID
                                    */
/* вариант с подсказками */
t1.MON_ID=t6.MON_ID and -- +PREDORDER=4
t1.MON_ID=t2.MON_ID and /*+PREDORDER=6*/
t1.MON_ID=t4.MON_ID and /*+PREDORDER=3*/
t1.DOL_ID=t2.DOL_ID and /*+PREDORDER=5*/
t0.USER_ID=t1.USER_ID and /*+PREDORDER=2*/
t0.USER_ID=t4.USER_ID /*+PREDORDER=1*/
)
group by mon_id) as T_AV
where T_AV."Месяц"=T_OTCH."Месяц"
order by T_AV."Месяц" desc;