Лабораторная работа №6. Вариативные решения

 

Многие запросы можно выполнять как объединение и как подзапрос.

 

Пример SELECT Cont.FirstName, Cont.LastName FROM Person.Contact Cont WHERE Cont.ContactID IN (SELECT Emp.ContactID FROM HumanResources.Employee Emp WHERE Emp.HireDate LIKE '%1997%' )   Пример SELECT Cont.FirstName, Cont.LastName FROM HumanResources.Employee Emp JOIN Person.Contact Cont ON Emp.ContactID=Cont.ContactID WHERE Emp.HireDate LIKE '%1997%';  
Посмотрите план выполнения запросов с помощью меню Запрос – Показать план выполнения  
Объединения представляют собой основу многотабличных запросов в SQL. Объединения являются средством, выявляющим отношения, существующие между данными. Т.е. объединения применяются тогда, когда необходимо получить данные из нескольких таблиц одновременно.   Подзапросы обычно ближе к словесному описанию запроса, облегчают написание и чтение запроса. Подзапросы используются, в основном, когда необходимо вывести данные из таблиц, к которым обращается внешний запрос, а данные из таблиц подзапроса используются для сравнения или поиска записи во внешней таблице. Если есть вероятность, что подзапрос вернет NULL, то рекомендуется не использовать подзапрос.  
Пример SELECT Cont.FirstName, Cont.LastName, Emp.BirthDate FROM HumanResources.Employee Emp JOIN Person.Contact Cont ON Emp.ContactID=Cont.ContactID WHERE Emp.HireDate LIKE '%1997%';   Пример SELECT Cont.FirstName, Cont.LastName FROM Person.Contact Cont WHERE Cont.ContactID IN (SELECT ContactID FROM HumanResources.Employee WHERE VacationHours<= (SELECT AVG (VacationHours) FROM HumanResources.Employee ));  
Не может быть выполнен с помощью подзапроса, так как выводит данные из нескольких таблиц   Не может быть выполнен с помощью объединения, так как требуется вычисление агрегирующей функции и возврат значения во внешний запрос  
Выбор применяемых операций определяется удобством чтения запроса, производительностью конкретной СУБД, а также семантикой запроса.  
Пример SELECT VendorID FROM Purchasing.ProductVendor WHERE ProductID NOT IN (SELECT ProductID FROM Production.Product WHERE Style='M')   Пример SELECT VendorID FROM Purchasing.ProductVendor JOIN Production.Product ON Purchasing.ProductVendor.ProductID=Production.Product.ProductID WHERE Style<>'M'  
Результатом выполнения запроса будет список поставщиков, которые не поставляют товары для женщин.   Результатом выполнения запроса будет список поставщиков, которые поставляют какой-либо товар, не являющийся товаром для женщин.  
Подзапрос, содержащий NOT IN, нельзя преобразовать в эквивалентное объединение.  
Хотя конечный результат получается тем же самым, многие СУБД обрабатывают объединения намного быстрее, чем подзапросы. Стоит поэкспериментировать с тем и другим, чтобы определить, какой запрос работает быстрее.  
Пример SELECT Employee.EmployeeID FROM HumanResources.Employee Boss JOIN HumanResources.Employee Employee ON Boss.EmployeeID=Employee.ManagerID WHERE Boss.SickLeaveHours>=Employee.VacationHours;   Пример SELECT Emp.EmployeeID FROM HumanResources.Employee Emp WHERE Emp.VacationHours<= (SELECT Boss.SickLeaveHours FROM HumanResources.Employee Boss WHERE Boss.EmployeeID=Emp.ManagerID )  
Посмотрев меню Запрос – Показать план выполнения, можно увидеть, что внутренний оптимизатор запросов выполняет оба примера одинаково.  
Иногда вместо множественных условий WHERE удобнее использовать оператор UNION.  
Пример SELECT ProductID, Name, MakeFlag FROM Production.Product WHERE Style='U' OR ProductID=400   Пример SELECT ProductID, Name, MakeFlag FROM Production.Product WHERE Style='U' UNION SELECT ProductID, Name, MakeFlag FROM Production.Product WHERE ProductID=400  
Если условие фильтрации окажется более сложным или если понадобится выбирать данные из многих таблиц (а не только из одной), то оператор UNION может значительно упростить процесс
   
   
   
В большинстве СУБД используется внутренний оптимизатор запросов, комбинирующий операторы SELECT, прежде чем СУБД начинает их обработку. Теоретически это означает, что, с точки зрения производительности, нет реальной разницы между различными вариантами исполнения одного и того же запроса (объединение-подзапрос, where-union). На практике многие оптимизаторы запросов не всегда выполняют свою работу так хорошо, как следовало бы. Лучшим вариантом было бы протестировать оба метода и посмотреть, какой из них вам лучше подходит.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: