The Dixie Flatline (6/2/2011)
Gus:The reason I said use CASE is that you might have cases where the join to T2 succeeds but some other T2.column value is NULL anyway.
In that case, would you want to substitute the value from T2a?
I assume not, but if that assumption is wrong COALESCE or ISNULL would be appropriate.
Amy:
All CASE statements should test against T2.Var1 to see if the join succeeded. Would you post one or two of your actual CASE statements?
That makes sense. Hadn't thought of it that way.
- Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
Property of The Thread
"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
Can you explain why this is not just a simple OR ?
Asked and answered.
I would expect a "conditional join" to perform poorly.
__________________________________________________
Against stupidity the gods themselves contend in vain. -- Friedrich Schiller
Stop, children, what's that sound? Everybody look what's going down. -- Stephen Stills
I tested it out. The Double-LEFT join runs over 10 times faster when joining 100,000 rows to 9,000 rows. HOWEVER, the critical difference isn't performance. The Double-LEFT join produced the expected 100,000 rows in the result set. But the conditional joins produced over 180,000 rows in the result set. Apparently the optimizer produces a query plan that returns a row for EACH "OR" or "IN" condition.
create table sourceTable (RowID int identity(1,1) primary key, RowKey_1 int, RowKey_2 int)
--optional
--create nonclustered index IX_Source1 on sourcetable (Rowkey_1)
--create nonclustered index IX_Source2 on sourcetable (Rowkey_2)
create table joinTable (JoinID int identity(1,1) primary key, data varchar (100))
insert into joinTable (data)
select CAST(N as varchar)+' Data blah de blah de blah'
from tally
where N <=9000
declare @X INT = 10000
insert into sourceTable(RowKey_1,RowKey_2)
SELECT TOP 100000
ABS(CHECKSUM(NEWID())) % @X + 1 AS RowKey_1
,ABS(CHECKSUM(NEWID())) % @X + 1 AS RowKey_2
FROM Tally
declare @timer datetime = getdate()
select *
into #temp1
from sourceTable s
join joinTable j on (j.JoinID = s.RowKey_1 or j.JoinID = s.RowKey_2)
select DATEDIFF(ms,@timer,getdate()) as Conditional_Join
set @timer = getdate()
select *
into #temp3
from sourceTable s
join joinTable j on j.JoinID in (s.RowKey_1, s.RowKey_2)
select DATEDIFF(ms,@timer,getdate()) as IN_Join
set @timer = getdate()
select s.*,case when j.JoinID is null then j2.data else j.data end as data
into #temp2
from sourceTable s
left join joinTable j on j.JoinID = s.RowKey_1
left join joinTable j2 on j2.JoinID = s.RowKey_2
select DATEDIFF(ms,@timer,getdate()) as Double_Left_Join
select COUNT(*) as Conditional_Join from #temp1
select COUNT(*) as IN_Join from #temp3
select COUNT(*) as Double_Left_Join from #temp2
__________________________________________________
Against stupidity the gods themselves contend in vain. -- Friedrich Schiller
Stop, children, what's that sound? Everybody look what's going down. -- Stephen Stills
Viewing 10 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply