Below is an example of a query I might run where, for each category, I want the NumberOfCourses to represent not only that specific category but also any child categories under it. I think the query is fairly self explanatory.
select c.CategoryID, courses.MarketID, count(distinct courses.CourseID) NumberOfCourses
from Category c
join CategoryHierarchy tch on tch.HierarchyKey like '%~' + cast(c.CategoryID as varchar) + '~%'
join vLiveEvents courses on tch.CategoryID = courses.CategoryID
where courses.MarketID is not null
group by c.CategoryHumanID, courses.MarketID
When I run this as is it may take almost two minutes, however if I add the hint Option (Force Order)
then it only takes a few seconds to run. So my question is am I doing something wrong that's causing SQL to create a bad plan or is the SQL engine actually just not good at optimizing hierarchy joins like this?
I tried including the sql plan, but it's way too long and SO won't let me have that many characters. I'm happy to share it though if anyone can tell me how to do so.
EDIT: I guess probably not every knows how these kinds of hierarchies work. They hierarchy key will look something like ~1234~5678~9123~ where 1234 is the parent of 5678 which is the parent of 9123. By doing a like comparison on a CategoryID I can include all child categories in the results.