Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Тоу Д. -> "Настройка SQL. Для профессионалов" -> 59

Настройка SQL. Для профессионалов - Тоу Д.

Тоу Д. Настройка SQL. Для профессионалов — СПб.: Питер, 2004. — 333 c.
ISBN 5-94723-959-0
Скачать (прямая ссылка): nastroykasqldlyaprof2004.djvu
Предыдущая << 1 .. 53 54 55 56 57 58 < 59 > 60 61 62 63 64 65 .. 161 >> Следующая


SELECT Е.First JJame. Е.LastJJame. Е.Salary, LE.Description,

М.FirstJlame. М.Lastjame, LM.Descriptlon FROM Locations LM1 Employees M, Locations LE. Employees E WHERE E.Hire_Date > :1 AND E.Manager_ID-M.Employee_ID AND E.Location_ID-LE.Location_ID AND M.Location_ID-LM.Locatlon_ID

Во время разбора, когда работает оптимизатор, он не может знать, что параметру : 1, вероятно, будет назначено значение, соответствующее текущей неделе, поэтому он делает благоприятное предположение о селективности этого условия в Hi re_Date. Сделав такое предположение, он может не только запретить использование индекса по Hi re_Date (в зависимости от распределения данных), но также посчитать, что запросу понадобятся практически все строки из всех соединенных таблиц, и тогда CBO выберет полное сканирование таблиц с соединением хэшированием. Даже если вы заставите CBO использовать индекс по Hi re_Date, он все равно будет считать, что ведущее условие неселективно, и придерживаться своего неудачного выбора для других соединений и методов доступа к таблицам. В действительности это не является ошибкой оптимизатора. Он не может знать того, что знает разработчик приложения о вероятных значениях связанной переменной. И, как следствие, если вам необходимо принимать в создании плана большее участие, чем просто указать ALL_ROWS или FIRST_ROWS, велика вероятность того, что ваша помощь потребуется оптимизатору на всем протяжении его работы, чтобы исправить некоторые неверные предположения.
Управление планами в Oracle

117

ПРИМЕЧАНИЕ -----------------------------------------------------------------------------

Подсказки ALL_R0WS и FIRST.ROWS представляют собой безопасный способ первичной оптимизации. Если вы используете синтаксический оптимизатор, то вполне можете опробовать этот стоимостный подход, указав подсказку еще до того, как начнете искать наилучший план выполнения. Если результат окажется достаточно быстрым, то вы сможете сэкономить усилия. Если же вы уже используете стоимостную оптимизацию в режиме ALL_R0WS, то попробуйте FIRST_ROWS и наоборот. Если вашу проблему может решить подсказка optimizerjnode, значит, оптимизатор делает правильные предположения и ему можно доверять.

Подсказки для доступа к таблицам

Далее перечислены основные подсказки, управляющие методами доступа к таблицам.

¦ INDEXС<Имя_псевдонима> <Имя_индекса>). Требует от Oracle, когда это возможно, осуществлять доступ к псевдониму <Имя_псевдонима>, используя индекс с именем <Имя_индекса>. Повторяйте эту подсказку для всех комбинаций индекса и псевдонима, которые необходимо контролировать.

¦ FULL (<Иня_псевдонимз>). Рекомендует серверу, когдаэто возможно, осуществлять доступ к псевдониму <Имя_псевдонима>, используя полное сканирование таблицы. Используйте эту подсказку для всех необходимых операций полного сканирования таблицы.

¦ INDEX_DESC(<Имя_псевдонима> <Имя_индекса>). Рекомендует Oracle, когда возможно, осуществлять доступ к псевдониму <Имя_псевдонима>, используя индекс с именем <Имя_индекса>, обращаясь к строкам в обратном порядке (обратном по отношению к обычному порядку сортировки индекса). Повторяйте эту подсказку для всех комбинаций индекса и псевдонима, которые необходимо контролировать, хотя маловероятно, что это потребуется больше одного раза в запросе.

Подсказки INDEX и FULL достаточно распространены, и их легко использовать. Подсказка INDEX_DESC редко бывает полезной, но иногда она жизненно необходима. Например, если вы хотите получить все сведения о сотруднике, нанятом в апреле последним, можно использовать такой запрос:

SELECT *

FROM Employees E

WHERE Hire_Date>=TO_DATE('2003-04-01'.'YYYY-MM-DD')

AND Hire_Date< T0_DATE('2003-05-01' 'YYYY-MM-DD')

ORDER BY Hi re_Date DESC

Сотрудник, нанятый последним, будет перечислен в начале набора строк, возвращенных запросом. Чтобы избежать считывания всех данных для всех остальных сотрудников, нанятых в апреле, вы можете добавить в запрос условие AND ROWNUM=I. Ho иногда в таком случае вы получите нежелательный результат, так как (в зависимости от данных) Oracle будет применять это условие до выполнения сортировки по убыванию. Если Oracle проводит полное сканирование таблицы, запрос вернет первого сотрудника, нанятого в апреле, которого найдет в таблице, и, вероятно, это будет сотрудник, нанятый первым по времени. Если же Oracle использует сканирование диапазона индекса по Hi re_Date, то начнет, как это происходит с диапазонами по умолчанию, с нижнего края диапазона индекса и вернет первого сотрудника, нанятого в апреле. Однако подсказка INDEX_DESC и индекс
118

4. Управление планами выполнения

Empl oyee_Hi re_Date по столбцу Hi re_Date удачно решают эту проблему, возвращая нужную строку при помощи всего лишь одной операции логического ввода-выво-да для таблицы:

SELECT /*+ INDEX_DESC(E Employee_Hire_Date) */ *

FROM Employees E

WHERE Hire_Date>=TO_DATE('2003-04-011.'YYYY-MH-DD')

AND Hire_Date< T0_DATE('2003-05-01'.'YvYY-MM-DD')

AND ROWNUM=I

Обратите внимание, что я удалил явное упоминание ORDER BY, так как он создает ложное впечатление эффективности, и добавил условие для R0WNUM.
Предыдущая << 1 .. 53 54 55 56 57 58 < 59 > 60 61 62 63 64 65 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100