Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Cross Join?

Author  Topic 

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-18 : 15:12:30
I'm using TOAD for SQL Server and asked it to tune the following query:

SELECT 
RCI.fpartno,
RCI.fpartrev,
RCI.fdescript,
RCL.fdexpdate,
INM.fleadtime
FROM dbo.rclotc RCL
inner join dbo.rcitem RCI on RCL.fcrcitmkey = RCI.freceiver + RCI.fitemno
inner join dbo.inmast INM on RCI.fpartno = INM.fpartno and RCI.fpartrev = INM.frev
WHERE year(RCL.fdexpdate) > 1901


The optimal query it comes up with is:

SELECT RCI.fpartno, 
RCI.fpartrev,
RCI.fdescript,
RCL.fdexpdate,
INM.fleadtime
FROM dbo.rclotc RCL
CROSS JOIN dbo.inmast INM
INNER JOIN dbo.rcitem RCI
ON RCI.fpartno = COALESCE (INM.fpartno , INM.fpartno) AND INM.frev = RCI.fpartrev
AND RCL.fcrcitmkey = RCI.freceiver + RCI.fitemno
WHERE year(RCL.fdexpdate) > 1901


I've done some reading on Cross Joins, but I have no idea why it applied one here nor do I understand the use of the Coalesce statement.

Can someone point me in the right direction?

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-11-18 : 15:46:48
[code]SELECT RCI.fpartno,
RCI.fpartrev,
RCI.fdescript,
RCL.fdexpdate,
INM.fleadtime
FROM dbo.rclotc AS RCL
INNER JOIN dbo.rcitem AS RCI ON RCI.freceiver + RCI.fitemno = RCL.fcrcitmkey
INNER JOIN dbo.inmast AS INM ON INM.frev = RCI.fpartrev
AND COALESCE(INM.fpartno, INM.fpartno) = RCI.fpartno
WHERE RCL.fdexpdate) >= '1902-01-01'[/code]


E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-18 : 16:02:38
oops. I just realized I posted the same code twice. Now please look at my first script and Toad's suggestion.
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-11-18 : 16:09:25
Seems TOAD has some serious problems...



E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-18 : 16:42:03
I was quite confused but it recommended 8 scripts ahead of mine and they all involved a cross join.

And when I check the script output, it's right.

Can a SQL Jedi explain the bolded parts of the code to a humble Padawan Learner?
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-19 : 11:32:39
Anybody?
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-11-19 : 11:39:00
quote:
Originally posted by DavidChel

Anybody?


the CROSS JOIN returns a cartesian product between left and right part. so in this case it gives all possible combinations of dbo.rclotc table values with dbo.inmast.
The COALESCE looks redundant. as it has same field repeated inside. not sure why it modified code like this.
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-25 : 09:15:06
Here is the answer I got from the Toad Team. Does this make sense?

quote:
The CROSS JOIN was not the actual intention but changing the join path is. In the original SQL, the join order is first on dbo.rclo and dbo.rcitem, then the results of it is then join with dbo.inmast. In the optimization, we would change the order tables are joined and try different permutation. The alternative SQL has a different join order: First joining dbo.rclotc and dbo.inmast, then use the result to join with dbo.rcitem. Speed to process the different orders of joins are different depending on the data in your tables.



As for the COALESCE, it is a trick to force database using (or not using) an index. This is particular useful in joining condition where both sides of the condition are indexed. Take this SQL as an example:



SELECT * FROM TABLEA INNER JOIN TABLEB ON TABLEA.COLA = TABLEB.COLB



Assumed that both TABLEA.COLA and TABLEB.COLB are indexed. For a NESTED LOOP join, database may choose to use the value of TABLEA.COLA to search the index on TABLEB.COLB, or vice versa. However, if we want to enforce the use of index on TABLEA.COLA, we can rewrite the condition to: TABLEA.COLA = COALESCE(TABLEB.COLB, TABLEB.COLB) so that the use of index on TABLEB.COLB is not feasible.



I can't make sense of that explanation so early in the morning. What about you experts?
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-11-25 : 11:55:07
what they explains is that by introducing coalesce they are forcing query to use index if exists on left side column (in your case RCI.fpartno) and avoid using index on INM.fpartno. Using functions on column makes query engine not use index on columns if any.

Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-11-26 : 10:20:49
In case your interested, I received this link from one of the TOAD Developers which explains the unusual behavior.

http://www.toadworld.com/Community/Blogs/tabid/67/EntryID/69/Default.aspx
Go to Top of Page
   

- Advertisement -