SQL = 구조적, 집합적, 선언적 언어이다.
굉장히 어려운 표현이다. 있어보이는 척 하는 말 같다. 누군가 저렇게 설명하면서 "이게 SQL이야. 끝!" 한다면 다시는 그 사람한테 질문 할 일이 없을 것이다.ㅋㅋ
그래서 저 말을 좀 더 쉽게 풀어서 이야기 해 보겠다.
SQL이 없는 세상을 상상 해 보라. 즉 "SELECT"문이 없는데 디스크에 저장되어 있는 특정 데이터를 메모리로 가져와서 지금 코딩중인 변수에 저장해야 되는 상황이라고 가정해 보자. 디스크에 접근하기 위한 특정 객체나 메서드가 필요할 것이며 거기서 원하는 정보를 적절한 방법으로 탐색 해 메모리로 가지고 오는 로직을 코딩해야 된다.(재앙이다...)
백엔드 서비스 로직 짜기도 바빠 죽겠는데 지금 디스크에서 메모리로 데이터 가지고 오는 로직까지 코딩 해야되는 것이다.
이제 위에서 예시로든 재앙 같은 상황을 상상하면서 가장 처음에 언급한 문장을 다시 읽어 보자. 어떤가? 이제 어느 정도 받아들여지는 부분이 있지 않은가?
정리해 보면 우리는 SQL 이라는 언어를 사용해 필요한 데이터를 구조적으로 그리고 집합적으로 "선언만" 해서 데이터베이스 시스템으로 전달만하면 슈퍼맨 디비님께서 우리가 전달해 준 선언문만 보고 우리를 대신해 코드를 만들어 컴퓨터 cpu에 전달 한다는 것이다.(결국 컴퓨터라는 기계가 이해할 수 있으려면 누군가는 CPU가 실행할 로직을 절차적으로 코딩 해야된다.)
다시 말해서, SQL은 결과 집합을 기술 하는 언어이다. 그리고 이를 얻기 위한 절차적인 과정은 SQL을 전달 받은 데이터베이스가 "대신해서" 만들어 낸다
결국 우리는 구조적, 집합적으로 What만 선언한다.
대부분의 How는 데이터베이스가(옵티마이저)가 역할을 맡아 처리한다.
그렇다면 지금부터 우리는 선언만 하고 디비가 코드를 짜는 과정을 좀 더 세부적으로 들여다 보자!
과정의 세분화
- 코딩한 SQL이 데이터베이스로 전달 된다. - 여기까지는 개발자가
- DB의 옵티마이저가 해당 SQL을 받는다 - 이거는 DB가
- SQL 최적화 작업이 진행된다. - 이거는 DB가
- 로우 소스 코드가 생성된다. - 이거는 DB가
- 해당 로우 소스코드를 컴퓨터 cpu가 읽어서 데이터 결과물을 가지고 온다. - 이거는 OS 및 CPU가
1번 과정은 설명을 생략한다.
2번 과정 - 데이터베이스 시스템 내부에는 옵티마이저라는 놈이 있다. 우리가 how를 제외한 what만 정의해서 데이터베이스와 소통할 수 있게 해주는 대단히 위대한 존재라고 할 수 있다. 즉, 우리 대신 코딩을 해주는 기특한 녀석이다.
3, 4번 과정 - SQL 최적화 작업은 옵티마이저와 로우 코드 생성기가 진행한다. 진행 과정은 아래와 같다.
1. SQL 파싱:
a. 파싱 트리 생성(sql을 쪼개서 트리로 만든다.)
b. Syntex 체크. 해당 SQL의 문법을 검사한다.
c. Semantic 체크. SQL이 의미적으로 적절한지 검사한다.
2. 실행 계획 선정:
a. 다양한 실행 경로를 생성한다.(컴퓨터 디스트에서 결과 집합을 찾을 수 있는 가능한 방법들을 만들어낸다.)
b. 미리 수집해 모아둔 시스템 및 오브젝트 통계정보를 통해 실행 경로들의 비용을 비교한다.
c. 가장 효율적인 최적의 실행 경로를 선택한다.
3. 로우 소스 생성:
a. 로우 소스 생성기가 실행 가능한 코드 또는 프로시저 형태로 실행경로를 포맷팅(변환) 한다.
5번 과정 - 생성된 로우 소스 코드를 cpu가 실행하여 디스크에서 필요한 결과 데이터들을 찾아 메모리에 적재한다.
SQL => DB의 옵티마이저 => SQL 최적화 => 로우 소스 코드 생성
위와 같은 과정을 통해 우리는 그저 구조적 그리고 집합적으로 무엇이 필요한지를 선언만 하면된다. 그 다음은 데이터베이스가 내부적으로 방법을 만들어내고 컴퓨터를 시켜 데이터를 찾아 메모리에 적재 하게 한다.
하지만, 완벽한것은 없다. 적어도 인간이 만든것 중에는 없다. 즉, 옵티마이저는 전지전능한 신이 아니다.
만약 지식인이자 느낌있는 개발자라면 다음과 같은 의심을 해볼 것이다.
- 미리 수집해 놓은 통계 정보를 통해 최적의 실행 계획을 결정한다?
- 만약 수집해 놓은 통계 정보에 오류가 있다면?
- 통계라는 것이 항상 최적의 판단을 내릴 수 있는 기준으로 적절한가? 아닌데?
- 컴퓨터의 내부 자원의 상태는 시시각각으로 변한다. 만약 내가 데이터를 요청한 시기에 컴퓨터가 일반적이지 않은 특수한 상황에 처해있다면?
- 네비게이션이 항상 최적의 경로로 우리를 안내하던가?(티맵? 네이버 지도? 카카오 네비?...)
결국 "옵티마이저도 실수를 한다" 라는 결론에 도달한다.
그렇기 때문에 DBA 및 백엔드 개발자는 쿼리 튜닝이라는 작업을 통해 옵티마이저를 도와 데이터 베이스가 최대한 효율적으로 요청을 처리할 수 있게 해야 한다. 그러면 어떻게 해야 우리가 옵티마이저를 도울 수 있을까?
정답은 "옵티마이저 힌트" 라는 것을 사용하여 SQL을 통해 데이터 엑세스 경로를 바꿀 수 있다. 결국 옵티마이저가 만드는 실행 계획에 SQL을 통해 우리(개발자)가 관여할 수 있는 것이다.
긴? 글 여기까지 읽어주신 모든 분께 감사를 표한다.
다 읽고 "그래서 옵티마이저 힌트로 어떻게 하라는거지?" 라고 생각 하시는 분들에게 쿼리 튜닝에 대한 학습을 추천한다.(필자 또한 마찬가지다...ㅋㅋ)
필자가 공부한 내용들은 다음 글 링크를 통해 확인할 수 있다.
'관게형 DB' 카테고리의 다른 글
SQL 공유 및 재사용 (0) | 2024.05.27 |
---|---|
데이터 모델링 - 논리 모델 (0) | 2024.01.18 |
데이터 모델링 - 개념 모델 (2) | 2024.01.07 |