Здравствуйте, vdimas, Вы писали:
V>Кароч, дословно тебе была расписана следующая схема:
V>- есть запросы с параметрами или без (некие "уникальные");
V>- по каждому запросу с параметром или "уникальному" хранится НАБОР планов;
V>- говорилось о возможности компактного представления в памяти наборов всех (не выкинутых заведомо) планов всех запросов.
V>Набо-о-ор. Набор! Это такое множество. Их несколько, обычно, планов на запрос-то.
V>Много таких планов на каждый такой запрос.
V>Все хранятся.
V>Потому что не умеют порождаться в рантайм.
V>Раз, раз, приём, приём, вы еще с нами?
V>Их все надо породить в compile time и каким-то хитрым образом сохранить.
V>А раз их все надо хранить, неужели это не означало, что они могут понадобиться?
V>Ну Семён Семёныч!
V>Ну разумеется, конкретный план для запроса будет выбран из НАБОРА их в зависимости от:
V>- значений параметров;
V>- текущих значений статистики;
V>- текущего уровня дефрагментации индексов.
V>То бишь, какая там в опу "другая константа"?
V>Даже подавая одну и ту же константу в один и тот же запрос в разные времена жизни базы можно наблюдать выбор разных планов для исполнения.
Ухты. После ста страниц диагнозов профессионализма внезапно переходим к конкретике. Действительно, было бы лучше, если бы перед этой дискуссией кое-кто почитал учебники типа Гарсиа-Молина. Ну, чтобы понимать, как устроен "план запроса", чем физический план отличается от логического, и почему нет такого понятия, как "дерево планов запросов".
Компактное представление в памяти — это, конечно, интересно. Но для того, чтобы его конструктивно обсуждать, придётся понять, что именно хранится внутри этого таинственного "плана запроса".
А там, внезапно, в каждом узле хранится много "локальной" информации. Например, для пары таблиц, участвующих в Join, там будут храниться конкретные индексы, предикаты, и residuals для этого join. И их там как бы дофига, потому что потенциально
orders o join manager m on o.managerId = m.id порождает
бездну вариантов исполнения. Грубо говоря, мы можем использовать любой из 5-6 индексов по Manager, потому что а вдруг там в where что-то особенно селективное написано, и любой из 10-15 индексов по order. Итого получаем от полусотни до сотни вариантов исполнения этого join. А для вложенных подзапросов там вообще ад и израиль.
Но основная дупа для идеи "компактного представления" ещё и в том, что "внутри" каждого из этих вариантов плана вшиты детали "окружающего" запроса, то есть, если, к примеру, у меня там где-то затесался where ManagerName like @managerNamePrefix+'%', то у меня в аргументах джойна так и будет стоять не index, а результат index scan c соответствующим предикатом.
Это означает, что этот вот кусочек плана запроса я не смогу использовать в плане, построенном для другого запроса.
Шансов на то, что удастся что-то "склеить", т.е. сослаться на один и тот же узел плана запросов несколько раз из разных деревьев, очень мало. И чем больше размер поддерева, тем больше в нём специфики, и тем меньше шансов на повторное использование. Общая экономия будет близка к нулю. Так что можно косвенно оценить расходы места под статическую таблицу планов, почитав различные гайды для DBM. Там, где опытные камрады говорят "ну, в принципе 2GB под кэш планов — это немного". Причём в кэш попадают исключительно только те планы, которые были реально использованы движком — то есть из наших 50-100 кандидатов на простой join, в кэш попадёт 1. Если у нас есть большое разнообразие статистики (например,в одной стране менеджеров больше, чем заказов, а в другой — наоборот), то через какое-то время в кэш может попасть ещё пара вариантов.
Чтобы хранить прямо все-все-все варианты, нам потребуются сотни гигабайт. А для тех запросов, где вариантов немного, их и хранить особо незачем — проще построить их на ходу.
И вот всё это как бы очевидно людям, которые реально занимались оптимизацией реальных SQL запросов как full-time job, а не только единожды сдали 32х часовой курс реляционной алгебры 20 лет назад.
Поэтому и не получается конструктивной дискуссии — уж очень разный у вас с Иваном уровень подготовки. Тебе кажется, что он чего-то непонимает ровно потому, что он весь ход твоей мысли уже в голове воспроизвёл, получил результаты, прикинул их к реальности, и видит заблуждения, допущенные на самом начальном этапе.