|
|
Re: 1 dimension and 2 fact table -cartesian join [message #570996 is a reply to message #570989] |
Mon, 19 November 2012 21:30 |
|
swas_recall
Messages: 12 Registered: May 2012 Location: Bangalore
|
Junior Member |
|
|
Please find the details below on the problem faced..
Below are the table structures of the 3 tables out of which datedim is the conformed dimension and fact1 and fact2 are two fact tables.
SQL> create table datedim
2 (datekey number,
3 datevalue date);
Table created.
SQL> create table fact1
2 (cuskey varchar2(10),
3 issue_key varchar2(5),
4 weekkey number,
5 weekdate date);
Table created.
SQL> ed
Wrote file afiedt.buf
1 create table fact2
2 (product_key varchar2(10),
3 seller_key varchar2(5),
4 weekkey number,
5* weekdate date)
6 /
Table created.
The primary keys of the above tables are as below.
ALTER TABLE datedim
add CONSTRAINT date_pk PRIMARY KEY (datekey);
ALTER TABLE fact1
add CONSTRAINT date_pk PRIMARY KEY (cuskey,issue_key,weekkey);
ALTER TABLE fact2
add CONSTRAINT date_pk PRIMARY KEY (product_key,seller_key,weekkey);
If i fire the below query this is giving me a Cartesian product.
SQL> ed
Wrote file afiedt.buf
1 select f2.Product_key,f2.Seller_key,f1.Issue_key,f1.Weekdate
2 from
3 datedim d,fact1 f1,fact2 f2
4 where d.datekey=f1.weekkey and
5* d.datekey=f2.weekkey
6 /
My result should show the below columns in the result set combining the above 3 tables.
Quote:f2.Product_key,f2.Seller_key,f1.Issue_key,f1.Weekdate
Please let me know in this regard.
Thanks
|
|
|
|
|
Re: 1 dimension and 2 fact table -cartesian join [message #571014 is a reply to message #570996] |
Tue, 20 November 2012 02:19 |
John Watson
Messages: 8963 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Your code doesn't run, you are trying to re-use names:orcl> ALTER TABLE datedim
2 add CONSTRAINT date_pk PRIMARY KEY (datekey);
Table altered.
orcl>
orcl>
orcl>
orcl> ALTER TABLE fact1
2 add CONSTRAINT date_pk PRIMARY KEY (cuskey,issue_key,weekkey);
add CONSTRAINT date_pk PRIMARY KEY (cuskey,issue_key,weekkey)
*
ERROR at line 2:
ORA-02264: name already used by an existing constraint
orcl>
orcl>
orcl> ALTER TABLE fact2
2 add CONSTRAINT date_pk PRIMARY KEY (product_key,seller_key,weekkey);
add CONSTRAINT date_pk PRIMARY KEY (product_key,seller_key,weekkey)
*
ERROR at line 2:
ORA-02264: name already used by an existing constraint
orcl> and you need to add the foreign key constraints to tell Oracle what is going on. But I don't see how you can get a cartesian join from that. To check Michel's hypothesis, you can tell the optimizer that the tables are loaded:exec dbms_stats.set_table_Stats(user,'datedim',numrows=>100)
exec dbms_stats.set_table_Stats(user,'fact1',numrows=>1000000000)
exec dbms_stats.set_table_Stats(user,'fact2',numrows=>1000000000)
|
|
|
Re: 1 dimension and 2 fact table -cartesian join [message #571015 is a reply to message #571014] |
Tue, 20 November 2012 02:31 |
John Watson
Messages: 8963 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
I corrected your code and set the stats, and this is the plan 1 get:
Execution Plan
----------------------------------------------------------
Plan hash value: 2296331767
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10P| 559P| | 53G(100)|999:59:59 |
|* 1 | HASH JOIN | | 10P| 559P| 33G| 53G(100)|999:59:59 |
| 2 | INDEX FULL SCAN | DATE_PKF2 | 1000M| 22G| | 0 (0)| 00:00:01 |
|* 3 | HASH JOIN | | 1000M| 36G| | 16674 (100)| 00:00:04 |
| 4 | INDEX FULL SCAN | DATE_PK | 100 | 1300 | | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| FACT1 | 1000M| 24G| | 11304 (100)| 00:00:03 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("D"."DATEKEY"="F2"."WEEKKEY")
3 - access("D"."DATEKEY"="F1"."WEEKKEY")
orcl>
orcl>
so Oracle isn't doing a cartesian join, but it still expect 10P rows back. Then I added the FK constraints:alter table fact1 add constraint f1fk (weekkey) references datedim;
alter table fact1 add constraint f2fk (weekkey) references datedim; and the plan changes:Execution Plan
----------------------------------------------------------
Plan hash value: 3489621693
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000M| 46G| | 5538K (1)| 00:21:52 |
|* 1 | HASH JOIN | | 1000M| 46G| 33G| 5538K (1)| 00:21:52 |
| 2 | INDEX FULL SCAN | DATE_PKF2 | 1000M| 22G| | 0 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| FACT1 | 1000M| 24G| | 11304 (100)| 00:00:03 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("F2"."WEEKKEY"="F1"."WEEKKEY")
orcl> which avoids the dimension table completely.
|
|
|
Re: 1 dimension and 2 fact table -cartesian join [message #571055 is a reply to message #571015] |
Tue, 20 November 2012 09:50 |
|
swas_recall
Messages: 12 Registered: May 2012 Location: Bangalore
|
Junior Member |
|
|
Many Thanks for the explanation,you are correct that it does not form a cartesian at all.I will check my production query again why i was not getting the desired result set as it was giving me a number of rows but i expected only 30.
Also i was trying to analyse the below explain plan.
My question was why it does not uses date_pk index while doing a scan?
I have added the below PKs
ALTER TABLE datedim
add CONSTRAINT date_pk_d PRIMARY KEY (datekey);
ALTER TABLE fact1
add CONSTRAINT date_pk PRIMARY KEY (cuskey,issue_key,weekkey);
ALTER TABLE fact2
add CONSTRAINT date_pk2 PRIMARY KEY (product_key,seller_key,weekkey)
SQL> explain plan for
2 select f2.Product_key,f2.Seller_key,f1.Issue_key,f1.Weekdate
3 from
4 datedim d,fact1 f1,fact2 f2
5 where d.datekey=f1.weekkey and
6 d.datekey=f2.weekkey;
Explained.
SQL> SELECT *
2 FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 669027766
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40 | 2520 | 5 (20)| 00:00:01 |
|* 1 | HASH JOIN | | 40 | 2520 | 5 (20)| 00:00:01 |
| 2 | NESTED LOOPS | | 20 | 740 | 1 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | DATE_PK2 | 20 | 480 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN| DATE_PK_D | 1 | 13 | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | FACT1 | 20 | 520 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("D"."DATEKEY"="F1"."WEEKKEY")
4 - access("D"."DATEKEY"="F2"."WEEKKEY")
Note
-----
- dynamic sampling used for this statement
22 rows selected.
Thanks
|
|
|