правильный дизайн запроса? перекрестные соединения управляют специальным интерфейсом отчетности

Я надеюсь, что некоторые из более опытных разработчиков баз данных/dwh или администраторов баз данных смогут оценить это:

Моя команда использует OBIEE в качестве внешнего инструмента для создания специальных отчетов, которые делают наши бизнес-подразделения.

Существует много задержек при генерации наборов, которые являются относительно небольшими. Нам предстоит ~ 1 час, чтобы создать ~ 50 тыс. записей.

Я изучил один из запросов, который ведет себя таким образом, и с удивлением обнаружил, что все таблицы, на которые ссылаются, подвергаются перекрестному соединению, а затем в предложении WHERE применяются фильтры.

Итак, чтобы проиллюстрировать, запросы обычно выглядят так:

SELECT ...
FROM tbl1
    ,tbl2
    ,tbl3
    ,tbl4
WHERE tbl1.col1 = tbl2.col1
and tbl3.col2 = tbl2.col2
and tbl4.col3 = tbl3.col3

вместо такого:

SELECT ...
FROM tbl1
INNER JOIN tbl2
    ON tbl1.col1 = tbl2.col1
INNER JOIN tbl3
    ON tbl3.col2 = tbl2.col2
INNER JOIN tbl4
    ON tbl4.col3 = tbl3.col3

Теперь, исходя из того, что я знаю о порядке операций запроса, предложение FROM выполняется перед предложением WHERE, поэтому первый пример будет выполняться намного медленнее, чем последний пример. Я прав (пожалуйста, ответьте, только если вы знаете ответ в контексте Oracle DB)? К сожалению, у меня нет прав администратора для запуска трассировки двух разных версий запроса.

Есть ли причина настраивать запрос первым способом, связанным с тем, как работает интерфейс OBIEE? Помните, что запрос является результатом перетаскивания пользователем атрибутов в песочницу из «банка» атрибутов. Предполагается, что выбор любой комбинации атрибутов будет генерировать выходные данные (если данные существуют). Атрибуты берутся из множества разных таблиц. У меня нет опыта разработки механизма, генерирующего SQL на основе такого произвольного выбора атрибутов, поэтому я не знаю, требуется ли структура запроса в первом примере для обслуживания такого рода средства создания отчетов.


person sion_corn    schedule 17.11.2014    source источник
comment
Эти два варианта запроса, вероятно, создают один и тот же план выполнения, который вам все равно следует просмотреть, если вы хотите найти узкое место.   -  person mustaccio    schedule 18.11.2014
comment
кросс-пост: dba.stackexchange.com/q/82878/1822   -  person a_horse_with_no_name    schedule 18.11.2014


Ответы (2)


Не волнуйтесь, исторически Oracle использовала первую нотацию для внутренних соединений, но позже приняла стандарты ANSI SQL.

Результаты с точки зрения производительности и возвращаемых наборов записей точно такие же, неявные соединения «запятая» не пересекают набор результатов, но эффективно интегрируют фильтры WHERE. Если вы сомневаетесь, запустите команду EXPLAIN SELECT для обоих запросов, и вы увидите, что прогнозируемые алгоритмы будут идентичными.


Расширяя этот ответ, вы можете заметить в будущем аналогичное обозначение (+) вместо внешних соединений. Этот ответ также будет правильным в этом контексте.

Настоящая проблема возникает, когда обе нотации (неявное и явное объединение) смешиваются в одном запросе. Это вызовет большие неприятности, но я сомневаюсь, что вы найдете такой случай в OBIEE.

person Sebas    schedule 17.11.2014
comment
хорошо, спасибо за информацию. +1. Я оставлю это открытым на некоторое время на случай, если кто-то еще что-то добавит. - person sion_corn; 17.11.2014
comment
Использование оператора (+) не рекомендуется Oracle. Oracle рекомендует использовать явный оператор OUTER JOIN, а не проприетарный (+). - person a_horse_with_no_name; 18.11.2014
comment
Попробую EXPLAIN SELECT - спасибо за помощь. - person sion_corn; 18.11.2014
comment
@a_horse_with_no_name: Спасибо! Я всегда хотел знать, каковы предпочтения Oracle. У вас есть источник для этого? - person wolφi; 29.05.2018
comment
@wolφi: руководство: Oracle рекомендует вы используете синтаксис OUTER JOIN предложения FROM, а не оператор соединения Oracle - person a_horse_with_no_name; 29.05.2018

Это внутренние соединения, а не перекрестные соединения, они просто используют для этого старый синтаксис, а не ANSI, как вы ожидали.

Большинство запросов на соединение содержат как минимум одно условие соединения либо в предложении FROM, либо в предложении WHERE. (Документация по Oracle)

Для простого запроса, такого как в вашем примере, выполнение должно быть точно таким же.

Там, где вы установили внешние соединения (в соединении бизнес-модели), вы увидите, что OBI создает запрос, в котором внутренние соединения выполняются в предложении WHERE, а внешние соединения выполняются в ANSI в выражении FROM — просто для того, чтобы действительно усложнить отладку. !

SELECT ...
FROM tbl1
    ,tbl2
    ,tbl3 left outer join
         tbl4 on tbl3.col1 = tbl4.col2
WHERE tbl1.col1 = tbl2.col1
and tbl3.col2 = tbl2.col2
and tbl4.col3 = tbl3.col3
person jackohug    schedule 18.11.2014
comment
спасибо за информацию, +1. Вы правы, я видел комбинацию специфических для Oracle внутренних соединений и ANSI LOJ, и это меня очень встревожило. Хорошо, чтобы прояснить это. Спасибо. - person sion_corn; 18.11.2014
comment
Я не уверен, когда вы нашли этот запрос, но это худшее, что можно сделать. см.: stackoverflow.com/a/11180050/1291428 - person Sebas; 18.11.2014
comment
@ Себас, я не говорил, что это хорошо. Это то, что производит ОБИ. Имеет более 5 лет, поэтому Oracle, похоже, не спешит его менять. - person jackohug; 19.11.2014