问题
I have a query that makes joins between 4 tables.
Matching my input params on a table by table basis yeilds the following
TrialBal - 8 million records matching entity and pl_date
Join to ActDetail - Execution is about 85 secs, the row count is 8672175 (with group by, the row count is 1...for now). ActDetail would return zero rows on an inner join.
Join to CalendarEngine - there are only 60 matchig records in this table (pl_date & entity), but when this is introduced to the SQL, the query just runs and runs. Is there any particular reason for this?
CalendarEngine has a composite index on entity and one other field not used in my query, so I should still be able to use it?
Why would the join between TrailBal and ActDetail be relatively quick (presumably the Outer join is running through all 8 million records against the count of 168k entries in ActDetail), but joining on 60 records in CalendarEngine leads to a seemingly endless loop.
SQL below (I need the commented out fields in the final query). Also tried Replacing the OR statement with 2 Outer Joins
SELECT
ad.acct_lv2 AS IFRS_lvl2,
ad.acct_lv3 AS IFRS_lvl3,
ad.acct_lv4 AS IFRS_lvl4,
ad.acct_lv6 AS IFRS_lvl6,
--(CASE WHEN tb.pl_date = cal.curr_me_date THEN cal.date END) as Reporting_Cycle_This,
--(CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END) as Reporting_Cycle_Last,
--(CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END) as Reporting_Cycle_Previous,
null as Total,
null as Balance_default_dim,
null as Balance_proxy_dim,
0 as percentage_bal_proxy_applied,
'1 Table Data' as rowType
FROM TrialBal tb
INNER JOIN Partition p ON p.partition_code = tb.partition_code
AND p.entity = tb.entity
LEFT OUTER JOIN ActDetail ah ON tb.actNum = ad.actNum
AND tb.cpny = ad.cpny
AND tb.pl_date = ad.pl_date
AND ad.source = 'Ground0'
--LEFT OUTER JOIN CalendarEngine cal on tb.pl_date = cal.curr_me_date OR tb.pl_date = cal.prev_me_date
--AND tb.entity = cal.entity
WHERE tb.pl_date = '2014-04-30'
AND tb.entity = 'My_entity'
GROUP BY ad.acct_lv2, ad.acct_lv3, ad.acct_lv4, ad.acct_lv6, --tb.actNum, tb.cpny,
CASE WHEN tb.pl_date = cal.curr_me_date THEN cal.date END,
CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END,
CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END
Also tried Replacing the OR statement with 2 Outer Joins:
LEFT OUTER JOIN sCalendar cal_cur on tb.pnl_date = cal_cur.curr_me_date
AND tb.entity_code = cal_cur.entity_code
LEFT OUTER JOIN sCalendar cal_pre on tb.pnl_date = cal_pre.prev_me_date
AND tb.entity_code = cal_pre.entity_code
回答1:
Is there an index on cal.curr_me_date and tb.pl_date ? When I have had similar issues I went looking for indexes on my joined fields and that was the fix.
回答2:
Why are you doing this join
LEFT OUTER JOIN ActDetail ah ON tb.actNum = ad.actNum
AND tb.cpny = ad.cpny
AND tb.pl_date = ad.pl_date
AND ad.source = 'Ground0'
I dont see any use, of the column, remove unnecesary joins.
if this part is date
tb.pl_date = '2014-04-30'
i suggest use
pl_date >= dateadd(d,0,datediff(d,0,pl_date)) and pl_date < dateadd(d,0,datediff(d,0,pl_date+1))
regards
来源:https://stackoverflow.com/questions/23936271/sql-joins-taking-forever-on-table-with-60-matches