Как я могу выбрать разные подсказки для разных объединений для одной таблицы в подсказке запроса?

StackOverflow https://stackoverflow.com/questions/2524248

Вопрос

Предположим, у меня есть следующий запрос:

select * from A, B, C, D
where A.x = B.x
and B.y = C.y
and A.z = D.z

У меня есть индексы на A.x и B.x, B.y и C.y и D.z

На A.z нет индекса.

Как я могу дать подсказку этому запросу, чтобы использовать подсказку INDEX в A.x, но подсказку USE_HASH в A.z?Похоже, что подсказки принимают только имя таблицы, а не конкретное объединение, поэтому при использовании одной таблицы с несколькими объединениями я могу указать только одну стратегию для всех них.

Альтернативно, предположим, что я использую ВЕДУЩУЮ или УПОРЯДОЧЕННУЮ подсказку по приведенному выше запросу.Обе эти подсказки также принимают только имя таблицы, так как я могу гарантировать, что объединение A.x = B.x выполняется перед соединением A.z = D.z?Я понимаю, что в этом случае я мог бы сначала перечислить D, но представьте, что D впоследствии присоединяется к E и что соединение D-E является последним, которое я хочу получить во всем запросе.

Третья конфигурация - предположим, я хочу, чтобы соединение A.x было первым из всего запроса, и я хочу, чтобы соединение A.z было последним.Как я могу использовать подсказку, чтобы выполнить одно соединение из A, за которым следует соединение B-C, и последним соединение A-D?

Это было полезно?

Решение

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

Подсказка INDEX может указать имя индекса, который вы хотите использовать, следующим образом:

SELECT /*+ INDEX (A, A_X_IDX) */ *
...

(предполагая, что индекс в A.X называется A_X_IDX).

Вы не можете сказать Oracle use использовать индекс в A.X и используйте хэш-соединение с таблицей A в том же операторе, это не имеет смысла.Однако вы можете (если необходимо) указать путь доступа для каждой таблицы примерно так:

SELECT /*+ INDEX (A, A_X_IDX) INDEX(B, B_Y_IDX) USE_HASH(C) */ *

Но, повторяю, это должно быть Редкий чтобы нужно было это сделать.Oracle вложила миллионы долларов и человеко-часы в разработку CBO, так зачем же ее эффективно отключать?

Другие советы

На SQL Server вы бы выполнили хэш-совместную подсказку следующим образом

SELECT * FROM table1 t1
INNER hash join table2 t2 ON  t1.id = t2.id

и вы также можете предоставить подсказку по индексу

select * from table1 t1
inner  join table2 t2 with (index( bla))  on  t1.id = t2.id

Не знаю, как выглядит синтаксис в Oracle, кстати, почему вы используете объединения в старом стиле?Ты все еще на 8i?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top