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