Подсказка очередности слияния результатов вычисления предикатов
Функция
Управление очередностью объединения результатов вычисления предикатов.
Спецификация
Синтаксические правила
-
Комментарий может быть:
-
строковый: исключает из выполнения только одну строку, перед которой стоят символы -- (два минуса);
-
блоковый: исключает из выполнения целый блок команд, заключенный между символами /* и */.
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;