I'm trying to get a query that's being generated by SSAS to perform acceptably. Because this query is (at least partially) generated by SSAS, I don't have complete control over the query text.
The problem - The query looks roughly like this:
select -- a bunch of columns from T1 -- table with ~40,000,000 rows inner loop join T2 on T2.t2id = T1.t2id -- table with ~16,000 rows inner loop join T3 on T3.t3id = T1.t3id -- table with ~200,000 rows
inner loop join T4 on T4.t4id = T1.t4id -- table with ~200,000 rows left loop join T5 on T5.t3id = T1.t3id and T5.t6id = T4.t6id -- table with 0 rows where -- some uninteresting conditions
T1 is a Fact (or Measure) table, T2, T3 and T4 are Dimension tables, T5 and T6 are involved in the filtering of the query. Every row of T1 WILL match exactly one row in each of T1, T2 and T3.
You'll note that I've hinted all of the joins - according to the documentation, using join hints forces join order (which is consistent with the plan that's produced). There's no mention that join hints can be transparently ignored by the optimizer, but that seems to be precisely what's happening.
In the plan that results, the join to T4 is done as a hash join, with T1*T2*T3 (40,000,000 rows) on the "top", so it ends up trying to build a hash table with 40,000,000 rows, resulting in very high tempdb activity and very poor performance (I don't know how poor - I've never let it finish).
I can see part of the reason why it's making this join choice - the estimate of T1*T2*T3 is only 35,000 rows, even though T1 has 40,000,000 rows and the join will hit on every row.
Questions:
1. What can I do to the query or the database to improve the estimate on the join to T3?
2. What can I do to the query to force the optimizer to use a loop join like I asked?
Version is SQL Server 2008 R2 SP2 Developer Edition X64.
OS is Windows 2008 R2
Machine is dual-quad-hyper-threaded CPU with 96Gb of RAM and several Tb of disk spread over 8 spindles and SSDs.
I've seen this query perform well before - I've been tuning this query for going on 7 years now and I've never seen it perform this badly that I can recall. Not sure if it's something that's changed in SP2, or something about the distribution of data in this particular database that's changed, but something's sure changed.
-cd Mark the best replies as answers!