Reputation: 13
I have the following query which takes about 20s to complete.
declare @shoppingBasketID int
select @shoppingBasketID = [uid]
from shoppingBasket sb
where sb.requestID = 21918154 and sb.[status] > 0
select
ingredientGroup.shoppingBasketItemID as itemID,
ingredientGroup.[uid] as groupUID
from shoppingBasketItem item
left outer join shoppingBasketItemBundle itemBundle on itemBundle.primeMenuItemID = item.[uid]
left outer join shoppingBasketItem bundleItem on bundleItem.[uid] = isnull(itemBundle.linkMenuItemID, item.[uid])
left outer join shoppingBasketItemIngredientGroup ingredientGroup on ingredientGroup.shoppingBasketItemID = isnull(itemBundle.linkMenuItemID, item.[uid])
left outer join shoppingBasketItemIngredient ingredient on ingredient.shoppingBasketItemIngredientGroupID = ingredientGroup.[uid]
where item.shoppingBasketID = @shoppingBasketID
The 'shoppingBasketItemIngredient' table has 40 millions rows. When I change the last line to the following the query returns the results almost instantly. (I moved the first select into the second select query).
where item.shoppingBasketID = (select [uid] from shoppingBasket sb where sb.requestID = 21918154 and sb.[status] > 0)
Do you know why?
Upvotes: 0
Views: 125
Reputation: 29647
You could add a query hint.
When using a variable the query optimizer could generate a slow execution plan. It's easier for a query optimizer to calculate the optimal plan when a fixed value is used.
But by adding the right hint(s) it could go for a faster execution plan.
For example:
select
...
where item.shoppingBasketID = @shoppingBasketID
OPTION ( OPTIMIZE FOR (@shoppingBasketID UNKNOWN) );
In the example UNKNOWN was used, but you can give a value instead.
Upvotes: 0
Reputation: 1269603
This is too long for a comment.
Queries in stored procedures are compiled the first time they are run and the query plan is cached. So, if you test the stored procedure on an empty table, then it might generate a bad query plan -- and that doesn't get updated automatically.
You can force a recompile at either the stored procedure or query level, using the option WITH (RECOMPILE)
. Here is some documentation.
Upvotes: 1