Natural join vs Cartesian product with equality condition [duplicate] - relational-algebra

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Explicit vs implicit SQL joins
I want to know the difference in performance of
select * from A,B,C where A.x = B.y and B.y = C.z
and
select * from A INNER JOIN B on A.x = B.y INNER JOIN C on B.y = C.z
Basically i want to know if inner join performs better than cartesian product?
Also, in inner join is cartesian product carried out internally?

First of All these two Operations are for Two different purposes , While Cartesian Product provides you a result made by joining each row from one table to each row in another table. while An inner join (sometimes called a simple join ) is a
join of two or more tables that returns only those rows that satisfy the join condition. Now coming to what You have Written here :
In case of Cartesian product First A table comprising of A,B,C is created and after that on the basis of what ever condition is given,we Get result. But as you see it's heavy process. On the other hand Inner join only chooses those result which are really fulfilling the given condition .Hence it's a better solution for achieving end results. First one is abuse of SQL language.

Related

Technical and syntax doubts about joins

i'm having a technical and syntax problem with JOINS in ORACLE.
If i have 7 tables, listed below:
FROM
QT_QTS.PLA_ORDEM_PRODUCAO pla,
qt_qts.res_tubo_austenitizacao aust,
qt_qts.res_tubo_revenimento1 res_rev1,
qt_qts.res_tubo_revenimento2 res_rev2,
limsprod.SAMPLE sp,
limsprod.test t,
limsprod.result r
I need to get ALL the data in the "limsprod.result r" table linked with similar corresponding data inside the qt_qts.res_tubo_austenitizacao aust, qt_qts.res_tubo_revenimento1 res_rev1 and qt_qts.res_tubo_revenimento2 res_rev2 tables.
How can I do this join using Oracle Database? I tried a left join, but it did not work.
It is impossible to answer that question. We have nothing but list of some tables. I'm not sure I'd even want to do that instead of you.
However, here's a suggestion: start with one table:
select * from limsprod.result r;
It'll return all rows. Then join it to another table:
select *
from limsprod.result r join qt_qts.res_tubo_austenitizacao aust on aust.id = r.id
and see what happens - did you get all rows you want? If not, should you add another JOIN condition? Perhaps an outer join? Don't move on to the third table until you sort that out. Once you're satisfied with the result, add another table:
select *
from limsprod.result r join qt_qts.res_tubo_austenitizacao aust on aust.id = r.id
join qt_qts.res_tubo_revenimento1 res_rev1 on res_rev1.idrr = aust.idrr
Repeat what's being said previously.

two oracle queries(one with AND , the other with OR) will return same result?

Is there any condition under which the two queries will yield different results?
select * from a,b,c where a.id = b.id(+) and a.id=c.id(+);
select * from a,b,c where a.id = b.id(+) or a.id=c.id(+);
I think in both cases, it will return the row if the id is in table a.
The second select fails with ORA-01719, Outer join operator (+) not allowed in operand of OR or IN.
Yet another reason to use ANSI JOIN syntax. You couldn't even conceive of this question if you were doing so.

INNER JOIN Optimization

I have two tables to join. TABLE_A (contains column 'a') and TABLE_BC (contains columns 'b' and 'c').
There is a condition on TABLE_BC. The two tables are joined by 'rowid'.
Something like:
SELECT a, b, c FROM main.TABLE_A INNER JOIN main.TABLE_BC WHERE (b > 10.0 AND c < 10.0) ON main.TABLE_A.rowid = main.TABLE_BC.rowid ORDER BY a;
Alternatively:
SELECT a, b, c FROM main.TABLE_A AS s1 INNER JOIN (SELECT rowid, b, c FROM main.TABLE_BC WHERE (b > 10.0 AND c < 10.0)) AS s2 ON s1.rowid = s2.rowid ORDER BY a;
I need to do this a couple of time with different TABLE_A, but TABLE_BC does not change... I could therefore speed things up by creating a temporary in-memory database (mem) for the constant part of the query.
CREATE TABLE mem.cache AS SELECT rowid, b, c FROM main.TABLE_BC WHERE (b > 10.0 AND c < 10.0);
followed by (many)
SELECT a, b, c FROM main.TABLE_A INNER JOIN mem.cache ON main.TABLE_A.rowid = mem.cache.rowid ORDER BY a;
I get the same result set from all the queries above, but the last option is by far the fastest one.
The problem is that I would like to avoid splitting the query into two parts. I would expect SQLite to do the same thing for me automatically (at least in the second scenario), but it does not seem to happen... Why is that?
Thanks.
SQLite is pretty light on optimization. The general rule of thumb: SmallTable Inner Join BigTable is faster than the reverse.
That being said I wonder if your first query would run faster in the following form:
SELECT a, b, c
FROM main.TABLE_A
INNER JOIN main.TABLE_BC ON main.TABLE_A.rowid = main.TABLE_BC.rowid
WHERE (b > 10.0 AND c < 10.0)
ORDER BY a;
Answer from the SQLite User Mailing List:
In short, because SQLite cannot read your mind.
To understand the answer compare speeds of executing one query (with
one TABLE_A) and creating an in-memory database, creating a table in
it and using that table in one query (with the same TABLE_A). I bet
the first option (straightforward query without in-memory database)
will be much faster. So SQLite selects the fastest way to execute your
query. It cannot predict what the future queries will be to understand
how to execute the whole set of queries faster. You can do that and
you should split your query in two parts.
Pavel

Why does this query result in a MERGE JOIN CARTESIAN in Oracle?

Here is my query:
select count(*)
from email_prod_junc j
inner join trckd_prod t5 on j.trckd_prod_sk = t5.trckd_prod_sk
inner join prod_brnd b on t5.prod_brnd_sk = b.prod_brnd_sk
inner join email e on j.email_sk = e.email_sk
inner join dm_geography_sales_pos_uniq u on (u.emp_sk = e.emp_sk and u.prod_brnd_sk = b.prod_brnd_sk)
The explain plan says:
Cartesian Join between DM_GEOGRAPHY_SALES_POS_UNIQ and EMAIL_PROD_JUNC.
I don't understand why because there is a join condition for each table.
I solved this by adding the ORDERED hint:
select /*+ ordered */
I got the information from here
If you specify the tables in the order you want them joined and use this hint, Oracle won't spend time trying to figure out the optimal join order, it will just join them as they are ordered in the FROM clause.
Without knowing your indexes and the full plan, it's hard to say why this is happening exactly. My best guess is that EMAIL_PROD_JUNC and DM_GEOGRAPHY_SALES_POS_UNIQ are relatively small and that there's an index on TRCKD_PROD(trckd_prod_sk, prod_brnd_sk). If that's the case, then the optimizer may have decided that the Cartesian on the two smaller tables is less expensive than filtering TRCKD_PROD twice.
I would speculate that it happens because of the on (x and y) condition of the last inner join. Oracle probably doesn't know how to optimize the multi-statement condition, so it does a full join, then filters the result by the condition after the fact. I'm not really familiar with Oracle's explain plan, so I can't say that with authority
Edit
If you wanted to test this hypothesis, you could try changing the query to:
inner join dm_geography_sales_pos_uniq u on u.emp_sk = e.emp_sk
where u.prod_brnd_sk = b.prod_brnd_sk
and see if that eliminates the full join from the plan

LINQ2SQL - Cross join emitted when I want inner join

This emits inner joins, which is what I want and works:
var q =
from itm in esdc.items
join itmImg in esdc.itemImages on itm.itemId equals itmImg.itemId
join itmIdent in esdc.itemIdentities on itm.imgIdentityId equals itmIdent.itemIdentityId
join startImgs in esdc.vStartPgImgs on itmImg.imgId equals startImgs.imgId
select ...
This works too, but cross joins were emitted. How do I get inner joins? I double checked the entities and the relationships are correct.
var q =
from itmIdent in esdc.itemIdentities
from itm in itmIdent.items
from itmImg in itm.itemImages
join startImgs in esdc.vStartPgImgs
on itmImg.imgId equals startImgs.imgId
select ...
If you need me to post the emitted SQL and the entity setup, let me know.
To put it simply: you get inner joins if you use the first form. Multiple from clauses represent cross joins (sort of, anyway 1) in LINQ.
Basically, if you want inner joins, use multiple join clauses.
1 (I say sort of because the subsequent sequences can depend on the earlier ones... but for LINQ to SQL they're almost always cross joins.)

Resources