개요
- Sort, Limit 연산은 실행계획에서 자주 등장한다.
- 그렇기 때문에 어떤 경우에 Sort와 Limit 연산이 발생하는지 짚고 넘어가려고 한다.
필수 사전 지식
테이블 세팅
create table team
(
team_id bigint,
team_name varchar(100),
created_at timestamp with time zone
);
데이터 세팅
INSERT INTO team (team_id, team_name, created_at)
SELECT i,
'Team ' || i,
CURRENT_TIMESTAMP - INTERVAL '1 day' * (i % 365)
FROM generate_series(1, 10000) AS i;
Sort
ORDER BY
를 처리할 때 주로 발생하며, 이외에도DISTINCT, GROUP BY, UNION
, 그리고 병합 조인(merge joins)과 같은 상황에서 발생한다.- 상당한 시작 시간(startup time)이 필요할 수 있다.
- 정렬이
work_mem
설정 내에서 수행될 수 있다면,빠른 퀵소트(quicksort)
알고리즘이 사용됩니다. - 정렬이
메모리 용량을 초과할 경우
,디스크로 이동하여 임시 파일을 사용
하는데, 이는비용이 많이 드는 작업
이 될 수 있다.
- Sort Method 부분을 보면
quicksort
방식이 사용되었으며, 이는메모리 내에서 정렬
이 이루어졌음을 의미한다. - 이번에는 데이터양을 좀 더 늘려보자. 1만 -> 100만 건으로 늘렸다.
INSERT INTO team (team_id, team_name, created_at)
SELECT
i,
'Team ' || i,
CURRENT_TIMESTAMP - INTERVAL '1 day' * (i % 365)
FROM
generate_series(1, 1000000) AS i;
- 이제 다시 실행계획을 살펴보자
- Sort Method 가 External Merge 방식으로 처리된 것을 확인할 수 있다. 이는
정렬작업을 work_mem에서 처리하기에 데이터양이 너무 커서 디스크에서 진행했음
을 의미한다. - 또한, 41520kb 만큼 메모리(work_mem)를 초과하여 필요한 추가 저장 공간을 디스크에서 확보했음을 의미한다.
- 따라서, External Merge 방식으로 정렬작업이 이루어지고 있다면, 인덱스를 통해서 Sort 작업을 처리하는 방법을 고려해봐야 한다.
- 위에서 볼 수 있듯이, 인덱스를 사용하면 Sort 연산을 대신처리할 수 있고, 데이터가 많은 경우 훨씬 좋은 성능을 볼 수 있다.
Limit
LIMIT과 OFFSET
를 처리할 때 주로 발생한다.- 그렇기 때문에 보통 패이징을 처리하는 쿼리의 실행계획에 등장한다.
- 이제 실행계획을 살펴보자.
- 먼저, 주목할 점은
(actual time=0.003..0.005 rows=50 loops=1)
이 부분이다.- 나는 처음에 rows가 20일 거라 생각했다. 그 이유는 31번째부터 50번째만 읽어올 거라 생각했다.
- 하지만, 50개의 데이터를 전부 읽어오고 그중 앞에 30개를 건너뛰고 20개만 반환해 주는 형태로 실행된다. 그렇기 때문에 rows는 50이다.
- 그렇다면, 페이징 처리에 있어서
OFFSET 값이 커질수록 읽어야 되는 데이터가 많아지기 때문에 실행시간은 증가
한다는 사실을 알 수 있다.
- 다음은
(cost=0.00..174.00 rows=10000 width=25)
이 부분이다.- 옵티마이저는 Seq Scan 연산의
예상 행 수를 계산할 때 LIMIT과 OFFSET을 고려하지 않는다.
따라서 전체 데이터 크기인 10000을 반환한다.
- 옵티마이저는 Seq Scan 연산의
References
'Database' 카테고리의 다른 글
PostgreSQL 실행계획 분석하기 6편 (서브쿼리) (0) | 2023.11.25 |
---|---|
PostgreSQL 실행계획 분석하기 5편 (Aggregates) (0) | 2023.11.25 |
PostgreSQL 실행계획 분석하기 3편 (Join Methods) (0) | 2023.11.19 |
PostgreSQL 실행계획 분석하기 2편 (Table Scan) (0) | 2023.11.18 |
PostgreSQL 실행계획 분석하기 1편 (실행계획 읽는 방법) (0) | 2023.11.16 |