
위 문제를 진행하며 겪은 쿼리의 개선과정을 공유합니다.
문제:
실험실에서 배양한 대장균들의 정보를 담은 ECOLI_DATA 테이블에서 대장균 개체의 ID(ID)와 자식 개체 수(CHILD_COUNT)를 출력하는 SQL 쿼리를 작성하는 문제입니다. 문제를 진행하며 생성형AI인 Gemini 의 쿼리 개선 방식을 참고했습니다.
1. A 쿼리:
SELECT
ID,
(SELECT COUNT(ID) FROM ECOLI_DATA WHERE PARENT_ID = ED.ID) AS CHILD_COUNT
FROM
ECOLI_DATA ED
ORDER BY
ID ASC;
2. B 쿼리(+ Gemini):
WITH CTE AS(
SELECT PARENT_ID AS ID,
COUNT(*) AS CHILD_COUNT
FROM ECOLI_DATA
GROUP BY PARENT_ID
)
SELECT ED.ID,
COALESCE(CTE.CHILD_COUNT,0) AS CHILD_COUNT
FROM CTE
RIGHT JOIN ECOLI_DATA ED ON CTE.ID = ED.ID
ORDER BY ED.ID ASC;
성능 비교:
| 테이블 레코드 | A 쿼리 | B 쿼리 |
|---|---|---|
| 적은 레코드 (10만 개) | ⏱️ 빠름 | ⏱️ 빠름 |
| 대량의 레코드 (1억 개) | 느림 | ⚡️ 빠름 |
분석:
GROUP BY 연산을 사용하여 자식 개체 수를 미리 계산하여 테이블 스캔을 줄입니다.결론:
CTE는 SQL에서 반복적으로 사용되는 서브쿼리를 저장하고 재사용할 수 있도록 하는 기능입니다. CTE를 사용하면 쿼리를 명확하고 간결하게 작성할 수 있습니다.
CTE 종류:
예시:
WITH
TEMP_TABLE AS (
SELECT
PARENT_ID AS ID,
COUNT(*) AS CHILD_COUNT
FROM
ECOLI_DATA
GROUP BY
PARENT_ID
)
SELECT
ID,
COALESCE(CHILD_COUNT, 0) AS CHILD_COUNT
FROM
TEMP_TABLE
ORDER BY
ID ASC;
예시:
WITH RECURSIVE
CHILD_COUNT_TREE (ID, PARENT_ID, CHILD_COUNT) AS (
SELECT
ID,
PARENT_ID,
1 AS CHILD_COUNT
FROM
ECOLI_DATA
WHERE
PARENT_ID IS NULL
UNION ALL
SELECT
EC.ID,
EC.PARENT_ID,
CHILD_COUNT_TREE.CHILD_COUNT + 1
FROM
ECOLI_DATA EC
INNER JOIN
CHILD_COUNT_TREE
ON
EC.PARENT_ID = CHILD_COUNT_TREE.ID
)
SELECT
ID,
CHILD_COUNT
FROM
CHILD_COUNT_TREE
ORDER BY
ID ASC;
성능 차이:
비교 요약:
| 기준 | 비재귀 CTE | 재귀 CTE |
|---|---|---|
| 데이터 규모 | 적은 데이터: ⏱️ 빠름 | 대량 데이터: ⚡️ 빠를 수 있음 |
| 쿼리 패턴 | 단순 계산: 효율적 | 복잡 계산: 간결하고 효율적 |
발전 방안:
추가 고려 사항:
참고: