2 вопроса (А и В) по оптимизации. Приемы использую давно, но в литературе не видел, принцип не понимаю, никто объяснить не может, верно ли это вообще?
A. Пусть TABLE - таблица с nullable внешним ключом T1.ID на первичный ключ TABLE1. Любой запрос типа I
Код:
select t1.CODE as T1_CODE
from TABLE t, TABLE1 t1
where t.T1_ID = t1.ID(+)
and %conditions%
эквивалентен запросу типа II
Код:
select
(select t1.CODE from TABLE1 t1 where t.T1_ID = t1.ID) as T1_CODE
from TABLE t
where %conditions%
Опытным путем выявлено, что запросы вида II работают не медленнее (а чаще быстрее), чем запросы I, хотя мне это не очевидно. Понятно, что вместо одной таблицы TABLE1 может быть несколько аналогичных таблиц TABLE1,...,TABLEn,
, чем больше таких таблиц, тем сильнее видна разница в скорости выполнения запроса (уже хорошо видно если переписать запрос с 3-я такими соединениями), и план выполнения выглядит полегче. Более, того, если таблицы TABLE, TABLE1,...,TABLEn связаны с помощью (+) каскадно:
Код:
t.T1_ID = t1.ID(+) and t1.T2_ID = t2.ID(+) and ... and t(n-1).Tn_ID = tn.ID(+)
и вся эта связь используется лишь для вычисления поля tn.CODE, то переписывание запроса с типа I на тип II еще сильнее уменьшает время его выполнения.
С другой стороны, если из TABLE1 нужно вытащить
полей, то чтобы переписать запрос к типу II, нужно выписать
подselect-ов, что при достаточно большом
только увеличит скорость выполнения запроса.
Вопросы такие:
1. За счет чего происходит уменьшение времени работы запроса при преобразовании его от типа I к типу II. Где об этом можно прочитать (при беглом взгляде на литературу ничего подобного не нашел).
2. Каково граничное значение
, при котором переписывание запроса из типа I в тип II не уменьшает время работы (для запроса с 2-я таблицами: TABLE t, TABLE1 t1)?
B. Пусть SPR, TBL таблицы, TBL имеет внешний ключ на SPR (интуитивно, SPR - таблица-справочник, в ней хранятся типы). Рассмотрим запрос типа I:
Код:
select
t.F1,...,t.Fk,
sum(t.G1) as G1,...,sum(t.Gn) as Gn
from TBL t, SPR s
where %conditions%
and t.F1 = s.F1 ... and t.Fk = s.Fk
group by t.F1,...,t.Fk
где (F1,...,Fk) - уникальный ключ в SPR. Часто вместо двух таблиц TBL, SPR используется множество таблиц с различными связями. Общий случай не выписываю ради простоты рассмотрения. Запрос данного типа I может быть преобразован в запрос типа II, использующий подзапросы, но не использующий group by:
Код:
select
t.F1,...,t.Fk,
(select sum(t1.G1) from TBL t1 where t1.F1 = t.F1 and ... and t1.Fk = t.Fk and %conditions%) as G1,
...,
(select sum(tn.Gn) from TBL tn where tn.F1 = t.F1 and ... and tn.Fk = t.Fk and %conditions%) as Gn
from SPR s
where %conditions%
Запросы типов I и II эквивалентны (т.е. при одинаковых входных параметрах возвращают одну и ту же таблицу) при условии, что таблица TBL содержит любой ключ из SPR.
Ясно, что при достаточно большом
и достаточно малом
запрос типа I работает быстрее, чем запрос типа II (можно проверить опытным путем). И ясно, что при достаточно малом
и большом
подзапрос типа II работает быстрее, чем запрос типа I (тоже можно проверить опытным путем). Можно предположить, что есть критическое соотношение
, до которого быстрее работает запрос одного типа, а после которого быстрее работает подзапрос другого типа. Каково
?
Или мне сразу на sql.ru топать?