[DB] Random Access (랜덤 액세스) 란?
들어가기 전에
업무 중에 성능 향상을 위하여 쿼리 튜닝에 대해서 공부하고 있었습니다. "랜덤 액세스"라는 단어를 맨 처음 봤을 때, '접근을 임의로 할 수 있다'라는 용어로 생각했습니다. 당연히 잘못 알고 있었기 때문에 공부하게 되었고, 실제 면접에서도 많이 질문이 들어온다고 하여서 해당 내용을 간단하게 정리하고자 합니다.
Random Access(랜덤 액세스) 란?
랜덤 액세스란 데이터를 저장하는 블록을 한 번에 여러 개 액세스하는 것이 아니라 한 번에 하나의 블록만을 액세스 하는 방식입니다.
한 번에 여러 개의 블록을 액세스 한다면(랜덤 액세스와 반대) 같은 양의 데이터에 대해 적은 횟수의 디스크 I/O가 발생하기 때문에 성능이 향상될 수 있습니다.
이렇게만 내용을 봤을 때는 랜덤 액세스 자체가 언제 발생하는지 어떤 상황에서 발생하는지를 알지 못했습니다. 아래 내용 참고 페이지에 코딩하는 흑구님의 블로그 및 구루비 홈페이지에 게시글을 확인한 결과 해당 내용을 확인할 수 있었습니다.
언제 랜덤 액세스가 발생하는 건가요?
인덱스를 액세스하여 확인한 ROWID를 이용하여, 테이블을 액세스 하는 경우 랜덤액세스가 발생하게 됩니다.
ROWID 는 해당 데이터를 찾아가는 유일한 주소 값이며 우리가 인덱스를 이용한다는 것은 인덱스로부터 조건을 만족하는 인덱스 값을 액세스 한 후 ROWID를 확인하여 ROWID 값으로 테이블을 액세스 하는 것을 의미합니다.
이해가 잘 안된다면, 랜덤 액세스 종류와 예시를 한 번 살펴봅시다.
랜덤 액세스 종류
확인 랜덤 액세스
SQL 의 WHERE 절, HAVING 절 조건에 의해 발생하는 랜덤 액세스입니다.
예를 들어,
WHERE 조건 : "전표번호", "전표일련번호"
인덱스 구성 : "전표번호"
위와 같은 조건으로 쿼리가 진행된다면, 인덱스에 설정된 "전표번호" 컬럼을 통해 처리범위가 감소됩니다. 그렇다면 인덱스에 포함되지 않은 "전표일련번호" 어떻게 되는 것일까요?
개발자는 "전표번호" 조건을 만족하는 데이터 중 "전표일련번호" 조건을 만족하는 데이터만을 결과로 추출해야 합니다. 그러나 "전표일련번호"는 인덱스에 포함되지 않기 때문에, "전표번호" 조건을 만족하는 모든 데이터에 대해 테이블을 액세스 하여 "전표일련번호" 칼럼의 값을 확인해야만 합니다. "전표일련번호" 컬럼은 인덱스에서 설정이 안 되어 있기 때문에 필터(filter) 역할을 하게 됩니다. 이 상황에서 확인 랜덤 액세스가 발생됩니다. 인덱스에 있는 "전표번호" 를 조회화여 ROWID 를 얻을 수 있고 테이블 ROWID 를 통해 실제 테이블에 접근하여 랜덤 액세스가 발생하게 됩니다. 이 때 ROWID SET 중에서 "전표일련번호" 컬럼의 필터(filter)에 의해 몇 개의 레코드들이 걸러지게 됩니다.
즉 WHERE 조건의 컬럼이 인덱스에 존재하지 않아 테이블을 액세스 하는 랜덤 액세스를 확인 랜덤 액세스라고 합니다.
확인 랜덤 액세스는 최종 출력의 결과가 랜덤 액세스의 횟수보다 더 적체 추출될 수 있다는 것입니다.
("전표일련번호"에 의해 걸러지는 데이터들이 존재할 수도 있기 때문에 최종결과 <= 랜덤 액세스라는 공식이 나옵니다.)
테이블에 액세스 되었지만 데이터를 버려야 한다는 것은 안타까운 일입니다. 인덱스를 선정할 때 확인 랜덤 액세스의 제거는 매우 중요한 포인트입니다. 다시 말해 쿼리 성능 향상을 고려한다면 확인 랜덤 액세스를 최소화하는 것이 중요합니다.
추출 랜덤 액세스
SELECT 절에 의해 발생하는 랜덤 액세스입니다.
예를 들어,
인덱스 구성 : "전표번호", "전표일련번호"
SELECT 컬럼 : ... "거래일자"
아시다시피 WHERE 문과는 비교하지 못할 정도로 SELECT 문에서는 수많은 컬럼을 호출할 것이고 심지어 전체 컬럼을 호출하는 경우도 있습니다. 확인 랜덤 액세스를 제거하여 인덱스가 "전표번호", "전표일련번호" 컬럼을 가지도록 수정하였습니다. 인덱스에 접근하여 ROWID 를 활용하여 SELECT 에 있는 모든 컬럼을 가져올 수 있다면 좋겠지만 인덱스에 포함되지 않은 "거래일자" 컬럼이 있습니다. 이런 경우 인덱스 엑세스 후 다시 테이블에 접근하여 해당 ROWID로 "거래일자" 등 SELECT 문에 있는 컬럼을 가져와야 합니다. 이런 랜덤 액세스를 추출 랜덤 액세스 라고 합니다.
추출 랜덤 액세스는 추출되는 데이터 결과의 양과 랜덤 액세스 횟수가 동일하다는 점입니다.
(SELECT에서는 WHERE 절처럼 추출되는 데이터를 증가시키거나 감소시키지 못합니다.)
정렬 랜덤 액세스
ORDER BY, GROUP BY 절에 의해 발생하는 랜덤 액세스입니다
정렬 랜덤 액세스 또한 랜덤 액세스의 횟수가 추출되는 데이터의 건 수가 동일하게 됩니다.
간단한 정리
추출 랜덤 액세스와 정렬 랜덤 액세스의 횟수는 추출되는 데이터 건 수에는 변화가 없습니다.
확인 랜덤 액세스의 경우 추출되는 데이터 양이 감소할 수 있고, 다시 말하면 버려지는 데이터가 존재할 수 있습니다.
개발자의 입장에서는 확인 랜덤 액세스가 랜덤 액세스 중에서 가장 많은 부하를 발생시키기 때문에 확인 랜덤 액세스를 제거하기 위해 노력해야 합니다.
참고 사이트