이번 포스팅에서는 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)를 도식화한 것인데요, 직관적으로 알기 쉽게 풀어놓아서 인용해봅니다. 

 

SQL Queries run in this order, by Brij Kishore Pandey

 

 

(순서 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

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요~! :-)

 

 

728x90
반응형
Posted by Rfriend
,