Disclaimer

Saturday, 30 May 2026

Cartesian product in the query

 

There should not be any Cartesian product in the query unless there is a definite requirement to do so. I know this is a silly point but we all have done this mistake at one point.


This is one of the most common SQL mistakes made by DBAs and developers.

What is a Cartesian Product?

A Cartesian Product occurs when two tables are joined without a proper join condition.

Oracle combines every row from Table A with every row from Table B.

Formula:

Rows Returned = Rows in Table A × Rows in Table B

Sample EMP Table

EMPNOENAMEDEPTNO
7369SMITH20
7499ALLEN30
7521WARD30
7566JONES20
7698BLAKE30

Total Rows = 5


Sample DEPT Table

DEPTNODNAME
10ACCOUNTING
20RESEARCH
30SALES

Total Rows = 3


Scenario 1 (Wrong Query - Cartesian Product)

Developer writes:

SELECT e.empno,
e.ename,
d.dname
FROM emp e,
dept d;

Notice:

NO JOIN CONDITION

Missing:

e.deptno = d.deptno

What Oracle Does

For each employee:

SMITH

Oracle pairs with:

ACCOUNTING
RESEARCH
SALES

Then:

ALLEN

pairs with all departments.

Result:

EMPNOENAMEDNAME
7369SMITHACCOUNTING
7369SMITHRESEARCH
7369SMITHSALES
7499ALLENACCOUNTING
7499ALLENRESEARCH
7499ALLENSALES
.........

Rows returned:

5 Employees × 3 Departments
= 15 Rows

instead of 5 rows.


Explain Plan

EXPLAIN PLAN FOR
SELECT e.empno,
e.ename,
d.dname
FROM emp e,
dept d;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

Plan:

--------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | MERGE JOIN CARTESIAN | |
| 2 | TABLE ACCESS FULL | EMP |
| 3 | BUFFER SORT | |
| 4 | TABLE ACCESS FULL | DEPT |
--------------------------------------------------

Important line:

MERGE JOIN CARTESIAN

Oracle is warning:

I found no join condition.
I am multiplying rows.

Layman Example

Imagine:

EMP Table

5 employees

A
B
C
D
E

DEPT Table

3 departments

HR
IT
Finance

Oracle produces:

A-HR
A-IT
A-Finance

B-HR
B-IT
B-Finance

C-HR
C-IT
C-Finance

D-HR
D-IT
D-Finance

E-HR
E-IT
E-Finance

Total:

15 combinations

This is Cartesian Product.




Scenario 2 (Correct Query)

SELECT e.empno,
e.ename,
d.dname
FROM emp e,
dept d
WHERE e.deptno = d.deptno;

Result:

EMPNOENAMEDNAME
7369SMITHRESEARCH
7499ALLENSALES
7521WARDSALES
7566JONESRESEARCH
7698BLAKESALES

Only:

5 rows

returned.


Explain Plan

---------------------------------------------------
| Id | Operation | Name |
---------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | HASH JOIN | |
| 2 | TABLE ACCESS FULL | EMP |
| 3 | TABLE ACCESS FULL | DEPT |
---------------------------------------------------

Notice:

HASH JOIN

instead of:

MERGE JOIN CARTESIAN

Good sign.


Real Production Disaster Example

Suppose:

ORDERS

10 Million Rows

CUSTOMERS

1 Million Rows

Developer writes:

SELECT *
FROM orders o,
customers c;

Missing join:

o.customer_id = c.customer_id

Oracle tries:

10,000,000 × 1,000,000

=

10,000,000,000,000
(10 Trillion Rows)

Consequences:

  • Huge CPU usage
  • TEMP tablespace fills
  • Query runs for hours
  • System slowdown
  • Other sessions get impacted

This is why DBAs fear Cartesian Products.


When Cartesian Product is Intentional

Sometimes it is required.

Example:

Generate all combinations.

SELECT color,
size
FROM colors,
sizes;

Colors:

Red
Blue

Sizes:

S
M
L

Result:

Red-S
Red-M
Red-L
Blue-S
Blue-M
Blue-L

Here Cartesian Product is intentional.


Interview Question

Q. How do you identify a Cartesian Product in an Explain Plan?

Answer:

Look for:

MERGE JOIN CARTESIAN

or check whether the query is joining multiple tables without a join condition.


DBA Golden Rule

Whenever a query joins multiple tables:

FROM emp e,
dept d

Immediately verify:

WHERE e.deptno = d.deptno

or

JOIN dept d
ON e.deptno = d.deptno

If not, Oracle may create a Cartesian Product, causing row multiplication, excessive CPU usage, large TEMP consumption, and severe performance problems.




No comments:

Post a Comment

Why should we always use table aliases in joins?

  Wherever multiple tables are used, always refer to a column by either using an alias or using the fully qualified name. Do not leave the g...