2014-11-17 2 views
2

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

Моя команда использует OBIEE в качестве инструмента для управления объявлением -hoc-отчетность осуществляется нашими бизнес-подразделениями.

При генерации множеств, относительно небольших, существует небольшая задержка. Мы сталкиваемся ~ 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? Помните, что запрос является результатом перетаскивания атрибутов пользователя в песочницу из «банка» атрибутов. Выбор любой комбинации атрибутов должен генерировать вывод (если данные существуют). Атрибуты поступают из разных таблиц. У меня нет опыта в разработке mecahnism, который генерирует SQL на основе такого типа выбора атрибутов ad-hoc, поэтому я не знаю, требуется ли дизайн запроса в первом примере для обслуживания такого типа средств отчетности.

+0

Эти два варианта запроса, вероятно, представляют собой один и тот же план выполнения, который вы должны просмотреть в любом случае, если хотите найти узкое место. – mustaccio

+0

перекрестная почта: http://dba.stackexchange.com/q/82878/1822 –

ответ

3

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

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


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

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

+0

приятно, спасибо за информацию. +1. Я оставлю это открытым на некоторое время дольше на случай, если кто-то еще что-то добавит. –

+0

Использование оператора '(+)' не рекомендуется Oracle. Oracle рекомендует использовать явный оператор 'OUTER JOIN', а не фирменный' (+) '. –

+1

Попробуем 'EXPLAIN SELECT' - спасибо за вашу помощь. –

1

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

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

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

Если вы установили внешние соединения (в объединении бизнес-модели), вы увидите, что 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 
+0

спасибо за информацию, +1. Вы правы, я видел комбинацию внутренних соединений Oracle и ANSI LOJs и был очень встревожен этим. Хорошо прояснить это. Благодарю. –

+0

Я не уверен, когда вы нашли этот запрос, но это самое худшее, что нужно сделать, когда-либо. см .: http://stackoverflow.com/a/11180050/1291428 – Sebas

+0

@Sebas Я не сказал, что это хорошо. Это то, что производит OBI. Имеет на 5+ лет, поэтому Oracle, похоже, не спешит его менять. – jackohug