본문 바로가기

데이터베이스

실행시간 (Execution time) vs 패치시간 (Fetch time)

지난주에 며칠 동안 데이터베이스 관련 앱 성능을 개선하는 작업을 진행했다.
가장 큰 테이블의 경우 row 가 몇 백만 개 정도가 되는 데, 그 테이블과 다른 테이블들을 조인해 만든 뷰들이 난리가 났다.
(데이터가 많고 정렬 쓰려면 결국 반정규화가 최고라는 교훈을 남겼는 데, 이건 따로 기록을 해둬야지)
문제가 되는 SQL 문을 돌려보니 fetch 시간이 600 초 가까이 되었고 좀 놀랐다. 실행시간은 생각보다 얼마 안 걸렸다.
집에 가는 길에 직장 동료에게 fetch 시간이 600 초가 넘었어요.. 하고 하소연을 했는 데,
동료가 fetch 시간이 뭐냐고 물었다. fetch 시간은 당연히 데이터를 가져오는 데 걸리는 시간이라고 기억하고 있는 데,
기억이 희미해 열심히 Oracle 공식 문서의 정의를 뒤져봤는 데, 찾지 못했다. 
다행히 괜찮은 사이트를 발견해 정독 중인데, 일단 까먹지 않게 실행시간과 패치 시간을 정리해 둔다.


 

데이터베이스 인스턴스의 옵티마이저가 사용자 요청한 SQL 문에 대해 최소 비용으로 처리 가능한 계획을 세운다.
이후 실행 계획에 따라 실행 과정이 반복된다. 이때 실행 과정에 걸리는 시간이 실행 시간이다.
실행 결과가 있으면 사용자에게 정해진 버퍼 사이즈만큼 전달하는 데 이때 걸리는 시간이 패치 시간이다.
보통 DDL 문은 실행시간 > 패치 시간, Select 문은 실행시간 < 패치 시간이라고 하는 데,
결과 데이터가 많으니 패치시간이 그렇게 오래 걸렸던 거다.
실행시간이 긴 것도 전체 데이터를 메모리에 올리는 데 조각조각 나눠서 올리며 작업을 수행해야 해서다.

아래는 추가 정보. 
데이터베이스 인스턴스란 데이터베이스에 접속해 데이터를 조작하는 애플리케이션이고, 메모리, 프로세스, 데이터베이스 버퍼, 로그 데이터 등으로 이루어져 있다.
데이터베이스 버퍼는 데이터를 읽을 때 제일 먼저 뒤지는 곳이고, 없으면 데이터베이스에서 파일을 읽어와 저장해두는 곳이다. 전체를 읽어오는 작업은 위에서 말한 것처럼 실행시간이 길며, 전체적으로 적중률에 별로 좋지 않은 영향을 미친다.

파서(parser)란 sql 문이 올바른 지, 사용자가 권한이 있는지, 캐시에 sql문이 있는지 찾아보는 단계이다.
oracle의 sql 트레이스 사용 통계 분석은 parse, execute, fetch 각각에 대한 횟수들이 요약되어 있다고 한다.
그래서 parse 1, execute 1, fetch 100 라면 sql 문 한번 수행에 100개의 결과 행을 반복적으로 패치했다는 뜻이라고 한다.

sql문 실행의 1단계가 커서 열기고 마지막 단계가 커서 닫기다. 커서일련의 데이터에 순차적으로 액세스 할 때 검색 및 현재 위치를 포함하는 데이터 요소이다.


sqld 딸 때 실행 계획부터 성의 없이 공부했는 데, 그러지 말걸 그랬다. 
다시 읽고 있으려니 앱 성능을 개선하는 데 필요한 점들이 보인다.  짬짬이 읽어야지..