SQL 실행과정

이재민·2023년 11월 13일

SQL이란, Structured Query Language 의 약자입니다.
DBMS에서 데이터를 정의, 조작, 제어하기 위해 표준화된 언어입니다.

실행 과정

MySQL 기준으로 SQL이 실행되는 과정은 크게 파싱, 최적화, 결과 반환 세 단계를 거쳐 수행됩니다.

1. 파싱(Parsing)

  • SQL 문장이 MySQL에 제출되면 SQL 파서 모듈을 이용해 파싱을 진행하고, 내부적인 데이터 구조(SQL 파스 트리)로 변환합니다.
    해당 단계에서 문법의 오류가 존재하는지 확인하고 올바른 데이터 구조인지 확인합니다.

2. 최적화(Optimization)

  • 파싱이 완료되면, MySQL은 쿼리를 최적화하여 가장 효율적인 실행 계획을 수립합니다.
  • 인덱스 사용 결정, 테이블 조인 순서 결정, 레코드 필터링 결정 등 최적화하여 성능을 향상시키려 노력합니다.
  • 옵티마이저의 종류로는 CBO(Cost Based Optimizer), RBO(Rule Based Optimizer) 두 가지 방식이 존재합니다.
    CBO는 비용을 기반으로 실행 계획을 세우는 방식으로 디스크 접근 횟수 등을 고려하여 최적의 실행 계획을 결정합니다.
    RBO는 규칙을 기반으로 실행 계획을 세우는 방식으로 미리 정의된 규칙을 사용하여 최적의 실행 계획을 결정합니다.
  • MySQL은 기본적으로 CBO를 사용하여 쿼리를 처리합니다.
사용자의 데이터는 분포도가 매우 다양하기 때문에
규칙 기반의 최적화는 이미 오래전부터 많은 DBMS에서 거의 사용되지 않고 있습니다.

3. 결과 반환(Result Retrieval)

  • 수립된 실행 계획대로 스토리지 엔진에 레코드를 읽어오도록 요청하고,
    MySQL 엔진에서는 스토리지 엔진으로부터 받은 레코드를 조인하거나 정렬하는 작업을 수행하여 클라이언트에게 결과를 반환합니다.

SQL 종류

1. DML

  • DML이란 데이터 조작어로 SELECT, INSERT, UPDATE, DELETE 명령어가 존재합니다.

2. DDL

  • DDL은 데이터 정의어로 CREATE, ALTER, DROP, RENAME, TRUNCATE 명령어가 존재합니다.
  • DDL은 데이터베이스에 존재하는 개체를 생성, 변경, 삭제하는 등의 작업을 수행합니다.

3. DCL

  • DCL은 데이터 제어어로 GRANT, REVOKE의 명령어가 존재합니다.

DROP, TRUNCATE, DELETE 차이점

DROP 명령어란, DDL 명령어이면서 테이블을 삭제하는데 사용됩니다.
해당 명령어를 통해 스키마의 모든 요소를 제거할 수 있지만, 복구가 불가능합니다.

  • DROP
    • 테이블을 제거할 수 있고, 테이블 정의 자체를 완전히 삭제합니다.
  • Truncate
    • 테이블을 최초 생성했던 초기상태로 만듭니다.
    • 용량이 줄어들고, 인덱스도 함께 제거됩니다.
    • 조건절이 필요없고 전체 삭제만 가능합니다.
  • Delete
    • 데이터만 삭제 되며 테이블의 용량은 줄어들지 않습니다
    • 로그 파일에 삭제 이력을 기록하기에 Rollback이 가능합니다.
    • Truncate에 비해서 수행 시간이 오래 걸립니다.

SELECT ~ FOR UPDATE

데이터베이스에서 제공하는 구문으로, 동시성을 제어할 때 사용할 수 있습니다.

  • SELECT ~ FOR UPDATE는 데이터를 읽을 때, 먼저 선점하여 다른 클라이언트의 요청을 막는 Pessimistic Lock(비관적 락) 방식이라고 할 수 있습니다.

  • 해당 구문을 통해 데이터의 일관성을 유지할 수 있습니다.

  • 또한, Redis와 같은 외부 프로세스를 이용하지 않고 데이터베이스 기능을 통해서 동시성을 제어할 수 있습니다.

    Pessimistic Lock(비관적 락) 방식은 데이터를 읽을 때 해당 데이터에 락을 획득하기 때문에 데이터 변경의 충돌 발생 가능성이 줄어듭니다.
    하지만, 동시성이 낮아지고 락 획득하기 위해 대기 시간이 발생하는 문제가 발생할 수 있습니다.
    
    Optimistic Lock(낙관적 락) 방식은 데이터 변경이 이뤄질 때 락을 거는 방식입니다.
    때문에 낙관적 락은 비관적 락과 다르게 충돌 발생 경우가 적은 때 사용합니다.
    낙관적 락은 데이터를 읽을 때 버전 번호와 같은 추가 정보를 함꼐 가져옵니다.
    데이터 변경시 해당 버전 번호를 이용하고, 다를 경우 충돌이라고 판단하여 다시 데이터를 읽어옵니다.
    하지만, 해당 경우에도 다른 클라이언트가 데이터 변경을 했을 수 있기에 충돌이 발생할 수 있습니다.
    때문에 낙관적 락을 사용할때는 예외처리에 주의를 기울여야 합니다.

서브쿼리(SubQuery)

서브쿼리란, SQL 쿼리 내에서 다른 쿼리를 포함한 질의문입니다.

서브쿼리(SubQuery) 종류

  1. 일반 서브쿼리
    • 단일행 서브쿼리: 쿼리 결과가 단일행만을 리턴하는 서브쿼리입니다.
    • 다중행 서브쿼리: 쿼리 결과가 다중행을 리턴하는 서브쿼리입니다.
    • 다중컬럼 서브쿼리: 쿼리 결과가 다중컬럼을 리턴하는 서브쿼리입니다.
  2. 스칼라 서브쿼리
    • 하나의 값을 반환하는 서브쿼리입니다. 주로 조건식이나 SELECT 목록에 사용됩니다.
    SELECT col1, (SELECT MAX(col2) FROM tab2) AS MaxValue
      FROM tab1;
  3. 인라인 뷰
    • 인라인 뷰는 FROM 절에 위치한 서브쿼리입니다. 테이블을 대체할 수 있습니다.
    SELECT col1
      FROM (SELECT col2, FROM tab1) AS inline_view
     WEHRE col2 < 5;
  4. 상호연관 서브쿼리(Correlative Subquery)
    • 메인쿼리와 서브쿼리가 서로 연관되어 있는 경우를 말합니다.
    • 메인 쿼리의 결과의 모든 행마다 서브쿼리와 정보를 주고받으며 연산하기에 데이터양이 많다면 성능상 좋지 않습니다.
    • 스칼라 서브쿼리와 마찬가지로 성능상 좋지 않습니다.
    SELECT col1,
    	   (SELECT t2.col2
              FROM tab2 t2
             WHERE t2.col1 = t1.col1) AS col2
      FROM tab1 t1
profile
문제 해결과 개선 과제를 수행하며 성장을 추구하는 것을 좋아합니다.

0개의 댓글