재귀 CTE 무한 루프, 순환 데이터를 막는 DB별 방법
WITH RECURSIVE로 카테고리 트리를 펼치다 순환 데이터 때문에 쿼리가 끝나지 않을 때, 경로 배열과 PostgreSQL 14 CYCLE 절, 깊이 제한으로 막는 방법을 PostgreSQL·MySQL·SQLite별로 비교한다.
JOIN, 서브쿼리, 윈도 함수처럼 SQL을 쓰며 알게 된 것
WITH RECURSIVE로 카테고리 트리를 펼치다 순환 데이터 때문에 쿼리가 끝나지 않을 때, 경로 배열과 PostgreSQL 14 CYCLE 절, 깊이 제한으로 막는 방법을 PostgreSQL·MySQL·SQLite별로 비교한다.
COUNT(*), COUNT(1), COUNT(컬럼)의 결과가 갈리는 NULL의 경우와 성능 통념을 MySQL과 PostgreSQL 문서로 검증한다. InnoDB에서 COUNT(*)가 느린 이유와 PostgreSQL에서 근삿값을 구하는 방법도 함께 다룬다.
ORDER BY를 붙인 윈도 함수에는 RANGE 기본 프레임이 따라붙어 누적합과 LAST_VALUE가 틀려 보입니다. 동점 행에서 ROWS와 RANGE가 갈라지는 지점을 실제 쿼리로 짚습니다.
사용자별 마지막 주문 같은 greatest-n-per-group 문제를 상관 서브쿼리, ROW_NUMBER, DISTINCT ON, LATERAL로 풀어 본다. PostgreSQL·MySQL·SQLite에서 되는 문법과 인덱스에 따른 성능 차이, 동점 처리를 정리했다.
LEFT JOIN에서 오른쪽 테이블 조건을 ON에 둘 때와 WHERE에 둘 때 결과가 갈리는 까닭을 예제 데이터로 따라가고, PostgreSQL·MySQL·SQLite가 외부 조인을 내부 조인으로 바꾸는 모습을 EXPLAIN으로 확인한다.
NOT IN 서브쿼리에 NULL 하나만 섞여도 결과가 0건이 되는 이유를 SQL 3값 논리로 한 단계씩 따라갑니다. NOT EXISTS와 LEFT JOIN IS NULL로 바꿨을 때의 결과와 실행 계획을 PostgreSQL, MySQL, SQLite에서 비교합니다.