Elinizin altında bir AdventureWorks veritabanı varsa, aşağıdaki iki sorgudan oluşan scripti çalıştırın. Ama çalıştırmadan önce, SQL Server Management Studio'nun sorgu ekranında "include actual execution plan" düğmesini tıklayın. Böylece sorgu sonucunuzun yanısıra bir sekmede execution plan görüntülenecektir. İşte script:
use
AdventureWorks
SELECT
C.CustomerID, COUNT(O.SalesOrderID) AS NumOrders
FROM
Sales.Customer AS C
LEFT OUTER JOIN Sales.SalesOrderHeader AS O
ON C.CustomerID = O.CustomerID
WHERE
C.Territoryid = 10
GROUP
BY C.CustomerID
HAVING
COUNT(O.SalesOrderID) > 5
ORDER
BY NumOrders;
use
AdventureWorks
SELECT
C.CustomerID, COUNT(O.SalesOrderID) AS NumOrders
FROM
Sales.Customer AS C
LEFT OUTER JOIN Sales.SalesOrderHeader AS O
ON C.CustomerID = O.CustomerID
WHERE
C.Territoryid = 10 and (O.SalesOrderID > 0 or O.SalesOrderID <= 0)
GROUP
BY C.CustomerID
HAVING
COUNT(O.SalesOrderID) > 5
ORDER
BY NumOrders;
İki sorgu, where satırındaki and (O.SalesOrderID > 0 or O.SalesOrderID <= 0) koşulu hariç tamamen aynı.
Execution planları incelediniz mi? Aralarındaki en önemli fark, ilk sorguda outer join yapılırken ikincide inner join yapılmış olması.
Where'e eklediğiniz koşul, sağ tablodan null değer dönmesini engelliyor. Left outer join'le inner joinin tek farkı ise, sağ tabloda karşığılı null olan satırların da sonuca dahil olmasıdır. Yani ikinci sorguda siz outer yazsanız da, pratikte bir inner join istemiş oluyorsunuz. Siz bunun farkında değilken, SQL Server fark edip gerekli optimizasyonu yapıyor.
Aferin sana zeki şey! : )
Kategori bazlı olarak tüm yazılarımı içeren blog'um için:
http://mustafaacungil.spaces.live.com