순서 보존
순서 보존 (Order Preservation)
DuckDB는 Pandas 같은 데이터 프레임 라이브러리와 비슷하게, 많은 연산에서 행의 순서를 보존해요. 오늘은 어떤 절(clause)이 순서를 보존하고 어떤 연산이 보존하지 않는지 함께 정리해 볼까요?
출처: 문서
본문
DuckDB는 Pandas 같은 데이터 프레임 라이브러리와 유사하게, 많은 연산에서 행의 순서를 보존해요.
예시 (Example)
예를 들어 다음 테이블을 보세요:
CREATE TABLE tbl AS
SELECT *
FROM (VALUES (1, 'a'), (2, 'b'), (3, 'c')) t(x, y);
SELECT *
FROM tbl;
| x | y |
|---|---|
| 1 | a |
| 2 | b |
| 3 | c |
다음은 x가 홀수인 행을 반환하는 쿼리예요:
SELECT *
FROM tbl
WHERE x % 2 == 1;
| x | y |
|---|---|
| 1 | a |
| 3 | c |
원본 테이블에서 (1, 'a') 행이 (3, 'c') 행보다 먼저 나타나기 때문에, 이 테이블에서도 그 행이 먼저 오는 것이 보장돼요.
절 (Clauses)
다음 절들은 원래 행 순서가 보존됨을 보장해요:
COPY(삽입 순서 참고)- 단일 테이블을 사용하는
FROM LIMITOFFSETSELECTUNION ALLWHERE- 빈
OVER절을 가진 윈도우 함수 - 위에서 언급한 구성 요소만 포함하는 한, 공통 테이블 표현식(CTE)과 테이블 서브쿼리
팁
row_number() OVER ()를 사용하면 원래 행 순서를 명시적인 컬럼으로 바꿔서, 기본적으로 행 순서를 보존하지 않는 연산에서 그 컬럼을 참조할 수 있어요. 구체화된 테이블에서는rowid유사 컬럼을 같은 용도로 사용할 수 있어요.
다음 연산들은 행 순서가 보존됨을 보장하지 않아요:
- 여러 테이블 및/또는 서브쿼리를 사용하는
FROM JOINUNIONUSING SAMPLE- 테이블 전체 집계 (입력 순서, 즉 행이 [순서에 민감한 집계 함수]({% link docs/current/sql/functions/aggregates.md %}#order-by-clause-in-aggregate-functions)로 들어가는 순서는 집계 함수에서 명시적으로 지정하지 않는 한 보장되지 않아요)
GROUP BY(입력 순서도 출력 순서도 보장되지 않아요)ORDER BY(특히ORDER BY는 안정적인 알고리즘을 사용하지 않을 수 있어요)- 스칼라 서브쿼리
삽입 순서 (Insertion Order)
기본적으로 다음 구성 요소들이 삽입 순서를 보존해요:
- [CSV reader]({% link docs/current/data/csv/overview.md %}#order-preservation) (
read_csv함수) - [JSON reader]({% link docs/current/data/json/overview.md %}#order-preservation) (
read_json함수) - [Parquet reader]({% link docs/current/data/parquet/overview.md %}#order-preservation) (
read_parquet함수)
삽입 순서 보존은 preserve_insertion_order [구성 옵션]({% link docs/current/configuration/overview.md %})으로 제어돼요.
이 설정은 기본값이 true로, 순서가 보존되어야 한다는 뜻이에요.
설정을 바꾸려면 다음을 사용하세요:
SET preserve_insertion_order = false;