SQL 레벨업 - 5장 반복문 (1/2)

2018-11-08

SQL에는 반복문이 없다. 설계에서 일부러 반복문을 제외 했다. 그 이유는 ‘그게 편하니까’ 라고 한다. ( ?????????????????? )

14강 반복문 의존증

내부적으로는 반복문 사용

일반적으로 사용자들은 하나의 레코드를 작은 SQL을 사용해 접근한다. 그리고 비즈니스 로직은 절차형 언어에서 반복 처리를 구현한다.

즉, SQL의 반복문이 없어도 자바나 C#에서 구현하면 된다. 이 방법은 틀린 방법이 아니다. SQL을 적용하기 힘든 작업에 무리하게 SQL을 사용할 필요는 없다.

반복이 없으면 프로그램의 생산성 향상 외에도 언급하지 않은 큰 장점애 생긴다. 반대로 말하면 반복계 코드에서 발생하는 큰 단점이다.

15강 반복계의 공포

  1. 반복계의 단점

같은 기능을 구현한다고 가정하면, 반복계로 구현한 코드는 포장계로 구현한 코드에 성능적으로 이길 수 없다.

  • SQL 실행의 오버헤드

SQL을 실행할 때는 데이터를 검색하거나 연산하는 실제의 SQL 처리 이외에도 다양한 처리가 이루어진다.

- 전처리

  1. SQL 구문을 네트워크로 전송
  2. 데이터베이스 연결
  3. SQL 구문 파스
  4. SQL 구문의 실행 계획 생성 또는 평가

- 후처리

  5. 결과 집합을 네트워크로 전송

1과 5는 실행하는 애플리케이션과 데이터베이스가 물리적으로 같은 본체에 있다면 발생하지 않는다. 하지만 일정 규모 이상의 시스템에서는 애플리케이션 서버와 데이터베이스 서버를 따로 분리하기 때문에 네트워크로 전송해야한다. 하지만 전송 속도 자체는 고속(거의 밀리초) 이기 때문에 오버헤드가 딱히 일어나지 않는다.

2는 데이터베이스에 SQL 구문을 실행하기 위한 작업이다. 데이터베이스에 연결해서 세션을 설정해야 하기때문에 발생하는 처리이다. 커넥션 풀을 사용하여 오버헤드는 거의 발생하지 않는다.

3과4에서 오버헤드에 가장 영향을 끼친다. 특히 3 SQL파스가 영향을 끼친다. 파스는 종류에 따라 다르지만 0.1초 ~ 1초 정도 걸린다. 다른 오버헤드들은 밀리초인 반면에 굉장히 큰 오버헤드이다. 그리고 파스는 데이터베이스가 SQL을 받을때마다 실행되므로 작은 SQL을 여러번 반복하는 반복계에서는 오버헤드가 더 클 수 밖에 없다. ( 파스를 반복하는 개수만큼 하니까! )

  • 병렬 분산이 힘들다.

반복계는 반복 1회마다 처리를 단순화 한다. 따라서 리소스를 부낫ㄴ해 병렬 처리하는 최적화가 안된다. CPU의 멀티 코어로 분산 처리를 할 수 없고, 저장소의 분산 효율이 낮다. 데이터베이스 서버 저장소는 대부분 RAID로 구성되어 I/O 부하를 분산할 수 있지만, 반복계는 SQL 구문이 대부분 단순해서 1회의 SQL 구문이 접근하는 데이터 양이 적다. 따라서 I/O를 병렬화 하기 힘들다.

하지만! 애플리케이션단에서 루프를 다중화 하면 된다.

  • 데이터베이스의 진화로 인한 혜택을 받을 수 없다.

데이터베이스가 처리해야 하는 양은 급격히 늘어나면서 그에 따라 ‘대규모 데이터를 다루는 복잡한 SQL 구문’을 빠르게 하는데 모든 노력이 중심이 되어 가고 있다. 따라서 단순한 SQL 구문을 빠르게 만드는것은 안중에도 없다.

따라서 반복계는 단지 느리기만 한 것이 아니라 느린 구문을 튜닝할 수 있는 가능성도 거의 없다 라는게 가장 크고 무서운 단점이다.

2. 반복계를 빠르게 만드는 방법은 없을까?

생각해볼 수 있는 선택지는 크게 3가지 이다.

  • 반복계를 포장계로 다시 작성

실제 상황에서 이러한 선택지를 사용할 수 없는 경우가 많다.

  • 각각의 SQL을 빠르게 수정

‘티끌모아 태산’이라는 말을 실천하는 선택지이다. 하지만 반복계에서 사용하는 SQL 구문으 너무 단순하기 때문에 어떻게 튜닝해야할지 알 수 없다.

결론 ‘티끌모아 티끌이다’

  • 다중화 처리

데이터를 분할할 수 있는 명확한 키가 없거나, 순서가 중요한 처리, 병렬화했을 때 물리 리소스가 부족하다면 이 방법은 사용할 수 없다.

결론

반복계의 튜닝은 선택지가 굉장히 한정적이다. 따라서 반복계로 만든 애플리케이션이 느리다면 대대적인 애플리케이션 수정을 각오해야 한다. 온라인 명세 출력처럼 수백개 정도만 반복한다면 성능이 충분히 괜찮게 나온다. 따라서 무조건 적대시 할 필요는 없다.

3. 반복계의 장점

  • 실행 계획의 안정성

실행 계획이 단순하다는 것은 해당 실행 계획에 변동 위험이 거의 없다라는 것을 나타낸다. 옵티마이저가 완벽하지 않은 현재 시점에서 안정적으로 성능을 확보할 수 있다는 것은 큰 장점이다.

반대로 이는 포장계의 단점이라고 할 수 있다. 포장계는 SQL 구문이 복잡한 만큼 실행 계획의 변동 가능성이 크다

  • 예상 처리 시간의 정밀도

실행 계획이 단순하고 성능이 안정적이라는 것은 추가적인 장점을 가져온다. 반복계의 처리 시간은 다음과 같은 간단한 식으로 표현할 수 있다.

< 처리시간 > = < 한 번의 실행 시간 > * < 실행 횟수 >
  • 트랜잭션 제어가 편리

트랜잭션의 정밀도를 미세하게 제어할 수 있다. 갱신 처리를 반복계에서, 특정 반복 횟수마다 커밋한다고 가정하면, 중간에 오류가 발생했다고 해도 중간에 커밋을 했기 때문에 해당 지점 근처에서 다시 처리를 실행하면 된다.

반면에 포장계는 갱신 처리중 중간에 오류가 발생한다면 처음부터 다시 실행해야 한다.