순서 보존

순서 보존 (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
  • LIMIT
  • OFFSET
  • SELECT
  • UNION ALL
  • WHERE
  • OVER 절을 가진 윈도우 함수
  • 위에서 언급한 구성 요소만 포함하는 한, 공통 테이블 표현식(CTE)과 테이블 서브쿼리

row_number() OVER ()를 사용하면 원래 행 순서를 명시적인 컬럼으로 바꿔서, 기본적으로 행 순서를 보존하지 않는 연산에서 그 컬럼을 참조할 수 있어요. 구체화된 테이블에서는 rowid 유사 컬럼을 같은 용도로 사용할 수 있어요.

다음 연산들은 행 순서가 보존됨을 보장하지 않아요:

  • 여러 테이블 및/또는 서브쿼리를 사용하는 FROM
  • JOIN
  • UNION
  • USING 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;

더 알아보기 (Learn more)