As an example, I want to get the list of all items with certain tags applied to them. I could do either of the following:
SELECT Item.ID, Item.Name
FROM Item
WHERE Item.ID IN (
SELECT ItemTag.ItemID
FROM ItemTag
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55)
Or
SELECT Item.ID, Item.Name
FROM Item
LEFT JOIN ItemTag ON ItemTag.ItemID = Item.ID
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55
GROUP BY Item.ID, Item.Name
Or something entirely different.
In general (assuming there is a general rule), what’s a more efficient approach?
Your second query won’t compile, since it references
Item.Namewithout either grouping or aggregating on it.If we remove
GROUP BYfrom the query:these are still different queries, unless
ItemTag.ItemIdis aUNIQUEkey and marked as such.SQL Serveris able to detect anINcondition on aUNIQUEcolumn, and will just transform theINcondition into aJOIN.If
ItemTag.ItemIDis notUNIQUE, the first query will use a kind of aSEMI JOINalgorithm, which are quite efficient inSQL Server.You can trasform the second query into a
JOIN:but this one is a trifle less efficient than
INorEXISTS.See this article in my blog for a more detailed performance comparison:
INvs.JOINvs.EXISTS