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

 

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

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

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


SELECT ...

FROM Departments D

WHERE EXISTS (SELECT NULL FROM Employees E

WHERE E.Department_ID=D.Department_ID+0)

Для противоположного порядка условие IN, заставляющее использовать другой порядок, от подзапроса к внешнему запросу, будет выглядеть так:

SELECT ...

FROM Departments D

WHERE D.Department^D IN (SELECT E.Department_ID+0 FROM Employees E)

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

Второй порядок соединения чаще всего будет работать плохо, за исключением необычных случаев, когда отделов больше, чем сотрудников!

У вас может быть несколько подзапросов, в которых база данных должна переходить от внешнего запроса к подзапросу (например, для подзапросов NDT EXISTS) или же ей следует придерживаться стандартного порядка. Такой случай подразумевает выбор порядка выполнения подзапросов. Также вы можете оказаться перед выбором — выполнять ли подзапросы после завершения внешнего запроса, при первой же возможности выполнить корреляционное соединение, либо принять некое промежуточное решение.
Универсальные техники управления планами

105

Первая тактика управления порядком выполнения подзапросов — просто перечислить их по порядку во фразе WHERE (то есть верхний подзапрос будет выполнен первым). Это один из редких случаев, когда порядок во фразе WHERE имеет смысл.

Иногда база данных выполняет подзапрос раньше, чем вам хотелось бы. Для коррелированных соединений — соединений в подзапросах, которые связывают подзапросы с внешними запросами, — работает та же тактика: просто откладывать соединения (см. раздел «Запрещение соединения в неправильном порядке»). Например, рассмотрим запрос:

SELECT ...

FROM Drders 0. Customers С. Regions R WHERE O.Status_Code = 'DP'

AND O.Customer_ID = C.Customer_ID AND C.Customer_Type_Code = 'GOV'

AND C.Region_ID = R.Region_ID AND EXISTS (SELECT NULL

FROM OrderJJetails OD WHERE 0.0rder_ID = 0D.0rder_ID AND 0D.ShIppedJr lag = 'Y')

Для этого запроса вы можете обнаружить, что подзапрос выполняется сразу же, как только достигается соединение с ведущей таблицей Orders. Однако вы хотите, чтобы до того, как потратиться на выполнение подзапроса, было выполнено соединение с Customers и отброшены неправительственные заказы. В таком случае для того, чтобы отложить корреляционное соединение, потребуются следующие изменения кода:

SELECT ...

FROM Orders 0. Customers С. Regions R WHERE O.Status Code = 'OP'

AND O.Customer_ID = C.Customer_ID AND C.Customer_Type_Code = 'GDV'

AND C.Region_ID = R.Region_I0 AND EXISTS (SELECT NULL

FROM Order_Details OD

WHERE 0.Drder_ID + 0*C.Customer_ID = 0D.0rder_ID AND OD.Shipped_Flag = 'Y')

Обратите внимание на добавление +0*С. Customer_ID к разделу WHERE подзапроса. Это гарантирует, что соединение с Customers будет выполнено первым, до выполнения подзапроса.

Предоставление стоимостному оптимизатору хороших данных

В любом стоимостном оптимизаторе (то есть для любого запроса, кроме запроса, выполняющегося с синтаксическим оптимизатором Oracle, так как только в Oracle есть такой) вторая по распространенности причина появления плохих планов выполнения после отсутствующих индексов — это отсутствие статистики по таблицам, столбцам и индексам, участвующим в запросе. В целом стоимостные оптимизаторы безо всякой помощи справляются с работой по поиску наилучшего плана, если у них есть хорошая начальная информация. Однако когда какой-либо информации не хватает, например, из-за того, что таблица или индекс были перестроены, а статистика не сгенерирована заново, оптимизатор может сделать просто ужасные предположения, которые приведут к серьезной потере производительности.
106

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

Если вы работаете в любой базе данных кроме Oracle или если вы используете стоимостный оптимизатор Oracle (он более распространен, и Oracle рекомендует использовать его) и не включаете синтаксический оптимизатор принудительно, то первое решение, которое вам следует попробовать, если вы не можете получить желаемый план выполнения, — заново сгенерировать статистику по всем таблицам и индексам, относящимся к запросу. Стандартной статистики обычно хватает для получения разумных планов выполнения.

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

SELECT ... FROM Orders WHERE Status_Code -1OP1
Предыдущая << 1 .. 46 47 48 49 50 51 < 52 > 53 54 55 56 57 58 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100