[PostgreSQL, Greenplum] SQL Query 실행 순서 (SQL order of execution)
Greenplum and PostgreSQL Database 2023. 3. 26. 22:37이번 포스팅에서는 SQL Query 의 실행 순서 (SQL Query order of execution) 에 대해서 알아보겠습니다.
1. 왜 SQL Query 실행 순서를 알아야 하는가? (Why does SQL Query Order matter?)
SQL Query 처리 순서는 Query 구문이 평가되는 순서를 정의합니다. Query 의 각 부분은 순차적으로(sequentially) 실행이 되므로, 쿼리의 실행 순서를 이해해야지만 어느 부분에서 무슨 결과에 접근할 수 있는지를 알 수 있습니다. SQL Query 순서를 정확하게 이해하는 것은 자주 접하게 되는 Query 의 도전사항, 혹은 실행되지 않는 Query의 문제를 해결하는데 필수적입니다. 그리고 SQL Query 의 처리성능을 최적화하고 속도를 향상시키는데에도 Query 실행순서를 이해하는게 큰 기여를 할 수 있습니다.
2. SQL Query 실행 순서 (SQL Query order of execution)
아래는 일반적인 SQL Query 의 구문입니다.
--------------------
-- SQL Query Syntax
--------------------
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
SQL Query 의 실행 순서는 아래와 같습니다.
순서 | 구문 | 기능 |
1 | FROM + JOIN | 대상이 되는 소스 테이블에서 데이터를 선택하고 Join 함. |
2 | WHERE | 1번에서 선택되고 Join 된 데이터를 Where 조건절에 맞게 필터링함. |
3 | GROUP BY | Group by 절의 기준 별로 데이터가 집계(aggregate)됨. |
4 | HAVING | 집계된 데이터를 Having 조건절에 맞게 필터링함. |
5 | SELECT | 최종 데이터를 반환함. |
6 | ORDER BY | 최종 데이터를 Order by 절의 변수를 기준으로 정렬(sorting)함. |
7 | LIMIT/ OFFSET | 행의 개수만큼 반환되는 데이터의 수를 제한(limit)함. |
아래는 이미지는 SQL Query 처리 순서(by Brij Kishore Pandey, LinkedIn/Twitter @brijpandeyji)를 도식화한 것인데요, 직관적으로 알기 쉽게 풀어놓아서 인용해봅니다.
(순서 1) FROM + JOIN 절
SQL 의 FROM +JOIN 절은 Query 에서 제일 먼저 실행되는 부분입니다. 따라서 메모리를 많이 사용하는 두 개의 큰 테이블을 Join 하기 전에 대상 테이블의 크기를 제한하거나 미리 집계(pre-agregate tables)를 해놓는다면 성능의 향상을 기대할 수 있습니다.
많은 SQL planner 들은 다른 Query 들의 최적화를 돕기 위해 로직과 다른 유형의 Join을 사용합니다. 가령, 아래의 SQL Query 의 경우, SQL Planner 는 where 절에 있는 조건절인 (table_a 에서 '30 <= age < 40' 로 필터) 를 먼저 실행하고, 그 다음에 Join 을 하는 것이 성능에 유리하고, 결과는 표준 SQL 처리 순서와 동일하게 반환하게 됩니다.
select
count(*)
from
table_a as a
join
table_b as b
on
a.id = b.id
where
a.age >= 30 and a.age < 40
PostgreSQL, Greenplum database 에서는 'EXPLAIN' 절을 사용해서 Query Plan 을 볼 수 있습니다.
(순서 2) WHERE 절
WHERE 절은 테이블의 칼럼 값으로 선택되고 Join 된 테이블 데이터를 제한하는데 사용됩니다. Where 절의 조건을 만족하지 않는 개별 행은 제거됩니다. Where 절에는 숫자형, 문자형, 날짜형, 블리언 등 어떤 데이터 유형도 사용가능합니다.
단, 대부분의 DB에서 Alias 는 사용할 수 없습니다.
(순서 3) GROUP BY 절
GROUP BY 절은 데이터의 각 개별 값들을 GROUP BY 'X' 의 각 그룹별로 sum(), count(), average(), min(), max() 등과 같은 집계 함수(aggregation functions)의 계산된 하나의 결과 값으로 요약해줍니다.
(순서 4) HAVING 절
SQL Query 에 GROUP BY 절이 있다면, HAVING 절의 제약 조건이 그룹별로 집계된 행에 적용되어서, HAVING 절의 조건을 만족시키지 못하는 그룹별 집계된 행(grouped rows) 를 제거하게 됩니다. WHERE 절처럼, 대부분의 DB에서 HAVING 절은 Alias 를 사용할 수 없습니다.
(순서 5) SELECT 절
위의 순서 1, 2, 3, 4 를 처리한 후의 데이터에 대해서 드디어 SELECT 절을 실행하여 칼럼 값을 계산하고 가져옵니다.
(순서 6) ORDER BY 절
위의 순서 1, 2, 3, 4, 5 번이 차례대로 실행된 결과의 데이터에 대해서 ORDER BY 절의 칼럼을 기준으로 오름차순(Ascending order) 또는 내림차순(Descending order) 으로 정렬을 해줍니다.
Query의 SELECT 절이 연산이 끝난 상태이므로, ORDER BY 절에서는 Alias 를 참조할 수 있습니다.
(순서 7) LIMIT / OFFSET 절
마지막으로, LIMIT 과 OFFSET 절을 사용해서 최종으로 반환되는 결과 값에서 행의 개수를 제한합니다.
* LIMIT number: 숫자 만큼의 행 출력
* OFFSET number: 숫자의 행부터 출력
예) select * from mytable LIMIT 10 OFFSET 5;
==> mytable 의 "5번째 행부터 (OFFSET 5)", "10개의 행을 출력(LIMIT 10)"
[Reference]
[1] SQL Query Order of Execution, by Sisense Team
: https://www.sisense.com/blog/sql-query-order-of-operations/
[2] SQL Lesson 12: Order of execution of a Query
: https://sqlbolt.com/lesson/select_queries_order_of_execution
이번 포스팅이 많은 도움이 되었기를 바랍니다.
행복한 데이터 과학자 되세요~! :-)