Подсказка очередности слияния результатов вычисления предикатов
Функция
Управление очередностью объединения результатов вычисления предикатов.
Спецификация
Синтаксические правила
-
Комментарий может быть:
-
строковый: исключает из выполнения только одну строку, перед которой стоят символы -- (два минуса);
-
блоковый: исключает из выполнения целый блок команд, заключенный между символами /* и */.
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*/;
-
Общие правила
-
Первыми будут объединяться результаты предикатов с наименьшими номерами. Если номер у предиката не задан (например, только у части предикатов группы заданы номера с помощью подсказок), то очередность будет определяться стандартным образом, но результаты «непронумерованных» предикатов будут добавляться в выборку данных после результатов «пронумерованных».
-
Порядок задания приоритетов должен устанавливаться экспериментальным путем.
Пример реального запроса пользователя СУБД ЛИНТЕР, который не мог быть оптимизирован без подсказок:
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;