Pull to refresh

Comments 36

UFO just landed and posted this here
Я лично не сравнивал оба оптимизатора Oracle и SQL Server, но не раз слышал от коллег по Oracle негативные отзывы о их оптимизаторе. Опыт работы таких специалистов — интегратор и более 10 лет с Oracle, что не должно вызывать вопросы в их компетенции.

Конкретно по вашему предположению, возможно Oracle просто не использует все возможные комбинации и выбирает из скудного списка, который, по их мнению, покрывает большинство ситуаций.

P.S. SQL Server то же работает и с 20 и более JOIN, вопрос как. Не всегда это получается быстро. К тому же я написал в разделе P.S., что выбор способа соединения таблиц это всего лишь одна из множество задач оптимизатора запроса.
Про оракловый оптимизатор даже книга отдельная есть, где не просто рассказывают «как оно работает», а на каждый аспект набор тестов, которые можно взять и по-запускать на своей базе.

После чтения такой книги, очень странно слышать слова «негативные отзывы от специалиста с 10 лет работы».
По SQL Server то есть есть книги на тему оптимизатора, с примерами и рекомендациями, но это же не значит что оптимизатор будет всегда прав, это просто невозможно (можно просто банально плохо написать запрос и никакой оптимизатор не поможет).
Планировщик запроса — это просто алгоритм. Он может быть плохим, конечно. Книжка которую я читал про оракловый, охватывала версии оракла 8, 9, 10, и автор прям наглядно показывал, как планировщику от версии к версии добавляют мозгов, и ситуации, когда эти «более умные» мозги принимают решения хуже, чем было.

Меня удивляет отношение человека, с опытом 10 лет.

В моём понимании, «планировщик запроса» — это такая данность, как восход Солнца. И довольно глупо ругать Солнце, что оно утром светит в окно и мешает спать. Самое простое — добавить к «окно на восток», хорошие светонепроницаемые шторы.

И кажется, профессионал должен не ругать Солнце, а сразу высказать, какие шторы, для каких случаев, и почему.




Кстати, отдельный вопрос — когда вообще нужно собирать результаты из 20-ти таблиц? Можно хотя0бы намекнуть на прикладную область, и что за данные такого рода запросом вытаскивали?

Согласен по поводу данности оптимизатора.

Что касается прикладной области, то в моём случае приложением организовано как 1С, из тучи «динамических» таблиц, с похожим названием, но проблема была даже не в этом. Проблема была в том, что генератор запросов на каждую галочку не добавлял параметров к уже существующим соединениям, а писал ещё 1 JOIN. То есть я мог наставить галочек и получить 10 JOIN с одной и той же таблицей и в каждом JOIN я делал ограничение по своему столбцу.
«Динамические» таблицы — это боль для RDBMS.
Как говорил мой знакомый, «по такой структуре БД хорошо диссертацию писать, но работать оно не будет».

Сколько интриги и метафор о книге про оптимизатор, а где же название-то? Общественность интересуется.

Одну из них, бесплатную, можно скачать вот тут — http://www.red-gate.com/products/sql-development/sql-prompt/entrypage/sql-query-optimizer-ebook

У bormotov, то же можете поинтересоваться про книгу по Oracle, если необходимо.
Ещё про оптимизатор Оракла полезно почитать книги мегагуру Тома Кайта — в разделе Библиография.
Он, кстати, очень не любит выкручивать руки оптимизатору хинтами и убеждён, что во многом проблемы производительности решаются правильной архитектурой БД.
И документацию Oracle Database 12c Release 2 Performance однозначно стоит почитать.

P.S. для меня тоже было странно услышать о таком мнении специалиста 10+ об оптимизаторе Oracle…
про оракловый оптимизатор вообще никаких интриг:

Дж. Льюис, ORACLE: Основы стоимостной оптимизации.

На русском издавали, например «Питер», аккурат десять лет назад.
Я могу не намекнуть, я могу пальцем показать: оборотно-сальдовая ведомость в 1С Бухгалтерия.
При «правильных» настройках планировщик Oracle разворачивает запрос её формирования более, чем в 1000 join из 50+ таблиц.

Возможно, группировки сильно ограничивают количество вариантов.

Я так и не понял из статьи, как именно MS SQL находит баланс между стоимостью плана и лимитом по времени перебора. N! вариантов — это хорошо для объяснения на пальцах, но вряд ли именно так все работает. У того же PostgreSQL помимо стандартного планировщика запросов есть ещё модуль генетической оптимизации. На последнем pgconf показывали модуль адаптивной оптимизации, который учитывал предыдущий опыт построения планов по схожим запросам. Наверняка в MS SQL все не менее наворечено и можно тоже что-то понастраивать с вычислением стоимости планов на большом количестве соединений. А просто сказать, что когда много таблиц, то планировщик начинает работать не очень… не информативно.
Как именно работает оптимизатор — это тема отдельной статьи, возможно я продолжу эту тему в новой статье.
Понимаете, просто само название статьи и начала абзацев вроде
Я бы хотел рассмотреть почему же SQL Server так долго строит план запроса.
Давайте поговорим о порядке соединения таблиц подробнее

настраивают на то, что на примере запроса из начала статьи будет разобран алгоритм построения плана и дана общая теория по специфике работы планировщика MS SQL. А закончится статья тем, что автор победил проблему с учётом вышеописанных знаний. По итогу же имеем «Вот запрос, нагенерированный 1С на 20 таблиц с повторами. Он строится иногда долго. Почему? Много таблиц в соединении плохо, так как эн-факториал. Вывод — не делайте много таблиц и уважайте планировщик». Ну такому уровню статей не место на Хабре, простите.
А так же я написал
Сегодня я не буду рассматривать варианты исправления ситуации, скажу только что в моём случае исправить генерацию запроса в приложении было невозможно.
Хорошо, спрошу максимально прямо — о чем эта статья и что из нееследует вынести после прочтения?
В первую очередь то, что выделил в статье курсивом

В данном вопросе очень важно понять — возможное количество соединений таблиц растёт по экспоненте, а не линейно


И вынес в раздел «вывод»

Относитесь более аккуратно к количеству JOIN в запрос и не мешайте оптимизатору. Если у вас не получается добиться нужного результата в запросе, где много JOIN, разбейте его на несколько, более мелких запросов и вы удивитесь на сколько лучше может получиться результат.


Для других — что оптимизатор это более сложная часть SQL Server и что о нём надо как минимум задумываться

Возможно кто-то даже решит заняться изучением оптимизатора основательно. Если хоть 1 человек примет такое решение — статья написана не зря.
да уж такой запрос на базе больше 10 строк это смерть.
если не секрет что за приложение такое нарисовало?

конструкция с in() обычно отрабатывается как loop что не способствует производительности

ну и план запроса неплохо бы в студию

а вообще любой планировщик бессилен против кривых рук
точно не 1С, там нет таких id… но очень похоже…

"Запросы с JOIN выполняются долго" — это наверное такая мантра, я часто это слышал. Но это далеко не всегда так. Даже если джойнятся большие таблицы. Даже если в запросе используется много джойнов.


Проблемы как правило либо в отсутствии нужных индексов, либо в наличии таких препятствий как OR и IN в условиях запроса, либо попытка обработки слишком большого объема данных в запросе. Или если понятно, что запрос будет отдавать одинаковые данные как с LEFT JOIN так и с INNER JOIN, то последний вариант может оказаться радикально эффективнее. Да что тут говорить, у каждого запроса в каждой СУБД могут быть свои особенности и этих особенностей не мало.


В приведенном запросе оптимизатор может нормально зацепиться разве что за условия


AND "pr"."area" IN (700) 
AND "pr"."deleted_by_user"=0 
AND "pr"."temporary" = 0

Но скорее всего эти условия сильно не ограничивают выборку, поэтому индексы не работают и приходится делать полный перебор. Подробности можно увидеть в EXPLAIN.

UFO just landed and posted this here
Сам запрос, приведён как яркий пример из моей жизни, чтобы можно было на основе реальных данных показать что бывает. На самом деле проблемы у этого запроса не в количестве JOIN, но он был показателен, в каких ситуациях возможны проблемы. В любой СУБД бывают моменты, когда разбиение запроса на части даёт существенный прирост в производительности. Так вот, суть вывода в том, что следует взять на вооружение, что если не помогает обычная оптимизация, то, возможно, поможет разбиение запроса. Я не предлагаю думать о проблемах количества JOIN ранее, чем с этим есть проблемы.
UFO just landed and posted this here
Ок, у меня нет цели вас переубеждать.

Скажу лишь то, что не хотел погружаться в оптимизатор в первой статье, но проблемы оценок в самом первом соединении, приведут к большим проблемам к концу запроса. Следовательно, чем больше цепочка, тем больше будет проблем на её конце.
UFO just landed and posted this here
При анализе хорошо бы указывать версию сервера БД, в разных версиях оптимизатор может вести себя достаточно по разному.
Запрос ужасен, надо что-то делать с тем сильным интеллектом, который его сгенерил, иначе если еще будут добавляться таблици, данных в таблицах станет существенно больше — будет полная жопа еще большая проблема.
Да, было бы неплохо посидеть на досуге и поразбирать этот заковыристый запрос. Неужели, в реальных приложениях «всё так плохо» (с запросами), или, всё-таки, структуры таблиц стараются такими, чтобы максимально упростить запросы?

И… что это за точки в тексте запроса:
"pr"."id" = "ufref3758_i16"."request"
Я немного отстал от жизни и мне требуется пояснить синтаксис.

«Псевдоним таблицы».«Имя её колонки»
Наверно лучше всё-таки «Псевдоним таблицы».«Имя её поля».
Колонки — это в экселе :)

"Псевдоним отношения"."Имя его атрибута" :) Таблицы — это в экселе, в реляционных СУБД — отношения :)

Это уже в реляционной алгебре, а не в живых RDBMS :)
Позволите мне рассказать анекдот про вашу статью?

Чапаев: А чего вся квартира в тараканах?
Петька: А это я диссертацию пишу. О тараканах.
Чапаев: Ну, расскажи.
Петька: Берем таракана, ставим его на стол и кричим: Беги! И он бежит! Отрываем ему ноги и кричим: Беги! Но он не бежит. Делаем вывод: таракан без ног не слышит!
Sign up to leave a comment.

Articles