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

 

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

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

Тоу Д. Настройка SQL. Для профессионалов — СПб.: Питер, 2004. — 333 c.
ISBN 5-94723-959-0
Скачать (прямая ссылка): nastroykasqldlyaprof2004.djvu
Предыдущая << 1 .. 108 109 110 111 112 113 < 114 > 115 116 117 118 119 120 .. 161 >> Следующая


Так как функционально полусоединение ничем не отличается от обычного соединения, вы можете добиться более высокой степени свободы в плане исполнения, явно исключив условие EXISTS и соединив подзапрос с внешним запросом. Например, рассмотрим такой запрос:

SELECT <Столбцы только из внешнего запроса>

FROM OrdeMMails 0D. Products P. Shipments S1 Addresses A. Code_Translations ODT WHERE 0D.Product_ID = P.Product_ID AND P.Unit_Cost > 100 AND 0D.Shipment_ID = S.Shipment_ID AND S.Address ID = A.Address ID(+)
232

7. Диаграммное изображение и настройка сложных SQL-запросов

AND DD.Status_Code = ODT.Code

AND ODT. CodeJype = 'Order_Detail_Status'

AND S.Shipment_Date > :now - I AND EXISTS (SELECT null

FROM Drders 0. Customers C. Codejranslations DT1 CustomerJypes CT WHERE C.CustomerJypeJD - Cf.CustomerJypeJD AND CT.Text - 'Government'

AND 00.OrderJD - 0.DrderJD AND D.CustomerJD - C.CustomerJD AND O.Status_Code - OT.Code AND 0.CompletedJlag - 'N'

AND OT.CodeJype - 'ORDERJTATUS'

AND OT.Text !- 'Canceled'T ORDER BY <Столбцы только из внешнего запроса>

Используя новые условные обозначения для полусоединений, этот запрос можно изобразить в виде диаграммы на рис. 7.29.

ODT

ОТ 0.8

Рис. 7.29. Сложный пример полусоединения с корреляционной связью с первичным ключом корневой детальной таблицы подзапроса

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

SELECT <Столбцы только из исходного внешнего звпроса>

FROM OrderJJetaHs OD. Products Р, Shipments S,

Addresses A, Codejranslations ODT.

Orders 0. Customers С. Codejranslations OT1 CustomerJypes CT WHERE OD,ProductJd - P.Product Id AND P.Un1t_Cost > 100 AND 0D.ShipmentJd - S.ShIpmentJd AND S.AddressJd - A.AddressJdT+)

AND 0D.StatusJode - ODT.Code

AND DDT.CodeJype - '0rder_Deta1l_Status'

AWD S.ShipmentJlate > :now~- I

AND C. CustomerJypeJd - CT. CustomerJypeJd AND CT.Text - 'Government'

AND OD.Order Id - 0.Order Id
Запросы с подзапросами

233

AND O.Customer_Id = C.Customer_Id AND O.Status_Code = ОТ.Code AND D.Completed Flag = 'N'

AND OT.CodeJType = 'DRDER_STATUS'

AND OT.Text != 'Canceled’

ORDER BY Столбцы только из исходного внешнего запроса>

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

OD

СТОГ

Рис. 7.30. Тот же запрос, преобразованный, чтобы слить подзапрос с внешним запросом

У этой новой формы есть существенные дополнительные степени свободы, позволяющие провести соединение с фильтрованным узлом P после соединения с хорошо фильтрованным узлом 0, но до соединения с практически не отфильтрованным узлом ОТ. В исходной форме базе данных пришлось бы полностью обработать всю ветвь подзапроса перед тем, как перейти к соединениям со следующими узлами внешнего запроса. Так как присоединение подзапроса в подобных случаях может только помочь и при этом получается диаграмма запроса, которую вы уже умеете оптимизировать, далее в этой главе я буду предполагать, что вы присоединяете подзапросы такого типа к внешним запросам. Я буду рассматривать только диаграммное изображение и оптимизацию других типов запросов.

Теоретически можно применять этот же трюк со слиянием подзапросов типа EXISTS, когда стрелка полусоединения указывает на детальный конец соединения, но это сложно и менее вероятно, что он поможет улучшить производительность запроса. Рассмотрим предыдущий запрос к отделам с условием EXISTS для Etnpl oyees:

SELECT ...

FRDM Departments D WHERE EXISTS (SELECT NULL

FROM Employees E

WHERE E.Department_ID = D.Department_ID)

Следующие проблемы возникают при попытке использовать такой же трюк в данном случае.

¦ Исходный запрос возвращает максимум одну строку на каждую строку из главной таблицы для каждого отдела. Чтобы получить такой же результат от преобразованного запроса с обычным соединением с детальной таблицей ( Empl oyees ),
234

7. Диаграммное изображение и настройка сложных SQL-запросов

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

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

Таким образом, редко возникает необходимость преобразовывать полусоединения в обычные соединения, когда стрелка полусоединения указывает вверх, разве что в тех случаях, когда детальный коэффициент соединения для полусоединения близок к 1,0 или даже меньше.

Чтобы завершить диаграмму для подзапроса типа EXISTS, вам нужны лишь правила вычисления корреляционного коэффициента предпочтения и уточненного коэффициента фильтрации подзапроса. Чтобы найти корреляционный коэффициент предпочтения, выполните следующие действия.
Предыдущая << 1 .. 108 109 110 111 112 113 < 114 > 115 116 117 118 119 120 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100