데이터베이스에서 조인은 두 개 이상의 테이블을 결합하여 하나의 결과 집합을 만드는 중요한 작업이다. 여러 가지 조인 유형 중에서 "카테시안 조인(Cartesian Join)"은 가장 기본적이지만 가장 비효율적인 조인 방식으로 알려져 있다. 이번 포스트에서는 카테시안 조인이 무엇인지, 그리고 실제로 어떻게 동작하는지 알아보겠다.
카테시안 조인은 두 테이블 간에 조인 조건을 지정하지 않고, 모든 가능한 행의 조합을 반환하는 조인 방식이다. 수학에서 데카르트 곱(Cartesian Product) 개념을 차용하여, 두 테이블의 모든 행이 서로 조합되는 방식으로 작동한다.
예를 들어, 두 개의 테이블 A와 B가 있다고 가정해보자.
테이블 A:
| A_id | A_value |
|---|---|
| 1 | A1 |
| 2 | A2 |
테이블 B:
| B_id | B_value |
|---|---|
| 10 | B1 |
| 20 | B2 |
카테시안 조인을 수행하면 다음과 같은 결과가 나온다.
결과:
| A_id | A_value | B_id | B_value |
|---|---|---|---|
| 1 | A1 | 10 | B1 |
| 1 | A1 | 20 | B2 |
| 2 | A2 | 10 | B1 |
| 2 | A2 | 20 | B2 |
보시다시피, 테이블 A의 각 행이 테이블 B의 모든 행과 조합되어 총 4개의 행이 반환되었다.
대부분의 경우, 카테시안 조인은 의도한 것이 아니라 실수로 발생한다. 이를 방지하기 위해 다음과 같은 조치를 취할 수 있다.
적절한 조인 조건 사용: 두 테이블을 조인할 때는 항상 적절한 조인 조건(ON 절이나 WHERE 절)을 사용하여 필요한 행만 조인되도록 한다.
SELECT *
FROM A
JOIN B ON A.A_id = B.B_id;
명확한 요구사항 확인: 조인을 수행하기 전에 정확히 어떤 결과를 원하는지 명확히 이해하고, 이에 맞는 조인 방식을 선택한다.
카테시안 조인은 모든 행의 조합을 반환하는 조인 방식으로, 특정 상황에서는 유용할 수 있지만 대부분의 경우 비효율적이고 의도하지 않은 결과를 초래할 수 있다. 따라서 항상 적절한 조인 조건을 사용하여 필요 없는 카테시안 조인이 발생하지 않도록 주의해야 한다.
두 현상 모두 행이 여러 블록에 걸쳐 저장되는 결과를 낳지만, 로우 체이닝은 행의 크기가 처음부터 큰 경우이고, 로우 마이그레이션은 행이 업데이트로 인해 크기가 커진 경우라는 점에서 차이가 있다. 이를 통해 각 현상의 발생 원인과 시점을 이해할 수 있다.
| DROP | TRUNCATE | DELETE | |
|---|---|---|---|
| 분류 | DDL | DDL (일부 DML 성격 가짐) | DML |
| Rollback | Rollback 불가능 | Rollback 불가능 | Commit 이전 Rollback 가능 |
| Commit | Auto Commit | Auto Commit | 사용자 Commit |
| Storage | 테이블이 사용했던 Storage를 모두 Release | 테이블이 사용했던 Storage 중 최초 테이블 생성 시 할당된 Storage만 남기고 Release | 데이터를 모두 Delete해도 사용했던 Storage는 Release되지 않음 |
| 정의 | 테이블의 정의 자체를 완전히 삭제함 | 테이블을 최초 생성된 초기 상태로 만듦 | 데이터만 삭제 |
| 일반형 함수 | 함수 설명 |
|---|---|
| NVL(표현식1, 표현식2) / ISNULL(표현식1, 표현식2) | 표현식1의 결과값이 NULL이면 표현식2의 값을 출력한다. 단, 표현식1과 표현식2의 결과 데이터 타입이 같아야 한다. NULL 관련 가장 많이 사용되는 함수이므로 상당히 중요하다. |
| NULLIF(표현식1, 표현식2) | 표현식1이 표현식2와 같으면 NULL을, 같지 않으면 표현식1을 리턴한다. |
| COALESCE(표현식1, 표현식2, ......) | 임의의 개수 표현식에서 NULL이 아닌 최초의 표현식을 나타낸다. 모든 표현식이 NULL이라면 NULL을 리턴한다. |
| 집계 함수 | 사용 목적 |
|---|---|
COUNT(*) | NULL 값을 포함한 행의 수를 출력한다. |
COUNT(표현식) | 표현식의 값이 NULL 값인 것을 제외한 행의 수를 출력한다. |
SUM([DISTINCT or ALL] 표현식) | 표현식의 NULL 값을 제외한 합계를 출력한다. |
AVG([DISTINCT or ALL] 표현식) | 표현식의 NULL 값을 제외한 평균을 출력한다. |
MAX([DISTINCT or ALL] 표현식) | 표현식의 최대값을 출력한다. (문자, 날짜 데이터 타입도 사용 가능) |
MIN([DISTINCT or ALL] 표현식) | 표현식의 최소값을 출력한다. (문자, 날짜 데이터 타입도 사용 가능) |
STDEV([DISTINCT or ALL] 표현식) | 표현식의 표준 편차를 출력한다. |
VARIAN([DISTINCT or ALL] 표현식) | 표현식의 분산을 출력한다. |
| 기타 통계 함수 | 벤더별로 다양한 통계식을 제공한다. |