Порядок таблиц в запросе соединения - PullRequest
7 голосов
/ 20 октября 2010

Я нашел этот параграф в документации Oracle

, если вы хотите выбрать имя каждого отдел вместе с названием его менеджер, вы можете написать запрос в один из двух способов. В первом примере что следует, подсказка / ++ упорядочена ++ / говорит, чтобы сделать соединение в порядке таблицы появляются в предложении FROM с попытка оптимизировать порядок соединения.

SELECT /*+ordered*/ d.NAME, e.NAME
FROM DEPT d, EMP e WHERE d.MGR = e.SS#

или:

SELECT /*+ordered*/ d.NAME, e.NAME 
FROM EMP e, DEPT d WHERE d.MGR = e.SS# 

Предположим, что есть 10 отделов и 1000 сотрудников, и это внутреннее таблица в каждом запросе имеет индекс столбец соединения. В первом запросе первая таблица дает 10 отборочных строки (в данном случае вся таблица). Во втором запросе первая таблица производит 1000 квалификационных рядов. первый запрос получит доступ к таблице EMP 10 раз и отсканируйте таблицу DEPT один раз. Второй запрос будет сканировать EMP стол один раз, но получит доступ к DEPT стол 1000 раз. Поэтому первый запрос будет работать намного лучше. Как эмпирическое правило, таблицы должны быть расположены с наименьшего эффективного количество строк до наибольшего эффективного количество рядов Эффективный размер строки таблицы в запросе получается применяя логические условия, которые решены полностью на этой таблице.

Но я не правильно понимаю это. Если в таблице t1 есть m строк, а в таблице t2 - n строк, разве механизм sql не пройдет через m x n строк в обоих случаях?

Обновление: Спасибо за все ответы. Я не буду переопределять оптимизатор, просто хочу подтвердить свою мысль.

Ответы [ 3 ]

4 голосов
/ 20 октября 2010

Что ж, в первом случае количество логических операций чтения составляет 10 + 10, во втором 1000 + 1000, при этом каждое отделение читается в среднем 100 раз.

Однако при написании запросов с хитом ORDEREDкак это не нормальная практика.Лучше оставить оптимизацию для оптимизатора большую часть времени.

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

Обычно оптимизатор выбирает лучший план выполнения, оптимальный порядок объединения таблиц.В случае, если оптимизатор не выдает хороший план выполнения, вы можете контролировать порядок выполнения, используя функцию HINTS SQL.Для получения дополнительной информации см. Справочник по Oracle Database Lite SQL.

- Руководство разработчика Oracle® Database Lite

2 голосов
/ 20 октября 2010

Это зависит от оператора WHERE.

SELECT /++ordered++/ d.NAME, e.NAME FROM DEPT d, EMP e WHERE d.MGR = e.SS#

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

SELECT /++ordered++/ d.NAME, e.NAME FROM EMP e, DEPT d

Это выберет всех сотрудников с названием отдела, в котором они работают. Так как на 1000 сотрудников ваш набор результатов будет иметь1000 строк.

JOIN никогда не заставит ваш движок зацикливаться на m x n строках, ваш набор результатов внутреннего соединения всегда будет m, если m < n

1 голос
/ 20 октября 2010

Вы действительно нашли это в документах oracle?

Вы не должны использовать подсказку ORDERED и позволить oracle принять решение за вас - в большинстве случаев это работает очень хорошо в наши дни.* Тем не менее, порядок соединения влияет на производительность.

В этом примере обсуждается NESTED LOOPS join:

Case 1:
 -> 1 lookup to find 10 rows in table A
 -> 10 index lookups in table B

Case 2:
 -> 1 lookup to find 1000 rows in table B 
 -> 1000 index lookups in table A
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...