[SQL] SQL 공유, 재사용

szlee·2023년 11월 16일
0

SQL

목록 보기
5/5

본 내용은 조시형님의 '친절한 SQL 튜닝' 책을 읽고 이해한 내용을 바탕으로 합니다.

[목표]

  • 소프트 파싱과 하드 파싱의 차이점을 설명할 수 있다.
  • 바인드 변수의 중요성을 이해할 수 있다.










소프트 파싱 vs 하드 파싱

소프트 파싱과 하드 파싱을 알아보기 전에 먼저 알아야할 개념이 있다.
바로 캐시다.
이름 처럼 무언가를 저장해두고 쓸 수 있는 거다.
그럼 SQL 관련해서 캐시는 어떤 역할을 할까?

라이브러리 캐시는 내부 프로시저를 반복 재사용할 수 있도록 캐싱해두는 메모리 공간을 말한다.

사용자가 SQL문을 전달했을 때 DBMS가 SQL을 파싱하고, 이 SQL이 라이브러리 캐시에 존재하는지 확인을 한다.

확인해봤을 때 캐시에 존재한다면 실행단계로 넘어가고, 없다면 최적화 단계를 거친다.

바로 여기에서~
캐시에서 찾아서 곧바로 실행단계로 넘어가는 것이 소프트 파싱
캐시에서 찾지 못해 최적화 및 로우 소스 생성 단계까지 모두 거치는 것이 하드 파싱이라고 부를 수 있다.

그리고 여기에서 소프트, 하드라고 부르는 의미는?
소프트는 가볍다, 하드는 어렵다!









SQL 최적화 과정은 왜 하드한가?

예를 들어 다섯 개 테이블을 조인하는 쿼리문 하나를 최적화하는 데도 무수히 많은 경우의 수가 존재한다.

조인 순서 - NL조인, 소트 머지 조인, 해시 조인 등..
테이블 전채 스캔? 인덱스 사용?
인덱스 스캔 - index range scan, index unique scan, index full scan, index fast full scan, index skip scan..
사용할 수 있는 인덱스가 테이블당 다수 일수도!


이렇듯 SQL 옵티마이저는 순식간에 엄청나게 많은 연산을 하고 그 과정에서 옵티마이저가 사용하는 정보는

  • 테이블, 컬럼, 인덱스 구조에 관한 기본 정보
  • 오브젝트 통계 (테이블 통계, 인덱스 통계, 컬럼 통계)
  • 시스템 통계 : CPU속도, Single Block I/O 속도, Multiblock I/O 속도
  • 옵티마이저 관련 파라미터

요렇게 하나의 쿼리를 수행하는 데도 후보군이 될 수 있는 엄청나게 많은 실행경로를 도출하고, 짧은 순간 딕셔너리와 통계정보를 읽어 각각에 대한 효율성을 판단하는 과정은 가벼울 수가.. 없다..
그리고 하드 파싱은 CPU를 많이 소비한다.
이렇게 어려운 작업을 거쳐 생성한 내부 프로시저를 한번만 사용하고 버리면 너무 비효율적이다!!
그래서 라이브러리 캐시가 필요한 것이다.









바인드 변수의 중요성

사용자 정의 함수, 프로시저, 트리거, 패키지 등은 생성할 때부터 이름을 갖는다.
컴파일한 상태로 딕셔너리에 저장되고 사용자가 삭제하지 않는 한 영구적으로 보관된다.
실행할 때 라이브러리 캐시에 적재함으로써 여러 사용자가 공유하면서 재사용한다.

그런데, SQL은 이름이 따로 없다!
무려 전체 SQL 텍스트가 이름 역할을 한다.
딕셔너리에 저장하지도 않고 처음 실행할 때 최적화 과정을 거쳐 동적으로 생성한 내부 프로시저를 라이브러리 캐시에 적재함으로써 여러 사용자가 공유하면서 재사용한다.

SQL자체가 이름이라 그 중 한 부분이라도 수정되면 그 순간 다른 객체가 새로 탄생하는거다.







아래와 같이 코드를 짰다면 각 고객에 대해 동시다발적으로 발생하는 SQL 하드파싱 때문에 과도하게 부하를 줄 것이다.

SELECT * FROM CUSTOMER WHERE LOGIN_ID='"+login_id+"';

의 결과

SELECT * FROM CUSTOMER WHERE LOGIN_ID='A';
SELECT * FROM CUSTOMER WHERE LOGIN_ID='B';
SELECT * FROM CUSTOMER WHERE LOGIN_ID='C';
...




이렇게 프로시저를 여러 개 생성하지 말고 로그인ID를 파라미터로 받는 프로시저를 공유하면서 재사용하는 것이 마땅하다.
바인드 변수는 바로 파라미터 driven방식으로 sql을 작성하는 방법이다.

SELECT * FROM CUSTOMER WHERE LOGIN_ID=?;


이 순간 라이브러리 캐시 조회해보면,

SELECT * FROM CUSTOMER WHERE LOGIN_ID= :1

-> 이렇게 SQL은 하나만 발견된다.

...

이 SQL에 대한 하드파싱은 최초 한번만 일어나고, 캐싱된 SQL을 다수의 고객이 공유하면서 재사용할 수 있다!

profile
🌱

0개의 댓글