I used SQL Server 2008 to these three variations of the aquery. In my testing I queries the AdventureWorks DB using ProductInventory in the Production schema. The three queries are:
declare @max int
Select @max = MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory]
SELECT TOP 1000 [ProductID]
,[LocationID]
,[Shelf]
,[Bin]
,[Quantity]
,[rowguid]
,[ModifiedDate]
FROM [AdventureWorks].[Production].[ProductInventory]
WHERE Quantity = @max
SELECT TOP 1000 [ProductID]
,[LocationID]
,[Shelf]
,[Bin]
,[Quantity]
,[rowguid]
,[ModifiedDate]
FROM [AdventureWorks].[Production].[ProductInventory]
WHERE Quantity = (Select MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory])
SELECT TOP 1000 AW1.[ProductID]
,AW1.[LocationID]
,AW1.[Shelf]
,AW1.[Bin]
,AW1.[Quantity]
,AW1.[rowguid]
,AW1.[ModifiedDate]
FROM [AdventureWorks].[Production].[ProductInventory] AW1
LEFT JOIN [AdventureWorks].[Production].[ProductInventory] AW2 ON AW1.Quantity < AW2.Quantity
WHERE AW2.ProductID IS NULL;
Using the "Show estimated query plan" icon I can compare the exection events for three cases. The results are:
- Declaring a variable and filling the variable is 5% faster than a sub-select in the where clause.
- The join is 98% slower than the subselect
- The join is 99% slower than the variable
My suggestion is to declare a variable and fill it. Use the variable in the WHERE clause