MySQL 서버의 옵티마이저가 실행 계획을 수립할 때 통계 정버와 옵티마이저 옵션을 결합해서 최적의 실행 계획을 수립한다.
옵티마이저는 옵션은 크게 조인 관련 옵티마이저 옵션과 옵티마이저 스위치로 구분한다.
이번 글에서는 옵티마이저가 조인의 성능을 최적화하는 기법중 하나인 MRR과 배치 키 엑세스를 알아보겠다.
DS-MRR(Disk Sweep Multi Range Read)라고도 한다.
MySQL 서버에서 지금까지 지원하던 조인 방식은 드라이빙 테이블에서 레코드를 한 건 읽어서 드리븐 테이블의 일치하는 레코드를 찾아 조인을 수행하는 것이다.
이는 네스티드 루프 조인(Nested Loop Join)이라고 한다. MySQL 서버의 내부 구조상 조인 처리는 MySQL 엔진이 처리하지만, 실제 레코드를 검색하고 읽는 부분은 스토리지 엔진이 담당한다.
이 때 드라이빙 테이블의 레코드 건 별로 드리븐 테이블의 레코드를 찾으면 레코드를 찾고 읽는 스토리지 엔진에서는 아무런 최적화를 할 수 없는 문제가 발생한다.
이러한 단점을 보완하기 위해 MySQL 서버는 조인 버퍼를 사용해 조인 대상 테이블 중 하나로부터 레코드를 읽어 그 값을 버퍼에 버퍼링하여 스토리지 엔진이 레코드를 읽을때 한 번에 요청하여 읽을 수 있도록 최소화한다. 이렇게 되면 정렬된 순서로 접근해 디스크의 데이터 페이지 읽기를 최소화할 수 있는 것이다.
물론 데이터 페이지가 메모리에 있다해도 예를들면 InnoDB 버퍼풀 그래도 버퍼풀의 접근을 최소화할 수 있는 것이다.
이러한 읽기 방식을 MRR이라고 하며, 이를 응용해서 실행되는 조인 방식을 BKA(Batched Key Access) 조인이라고 한다.
BKA 조인 최적화는 기본적으로 비활성화 되어있는데 이는 BKA 조인의 단점이 있기 때문이다.
쿼리의 특성에 따라 도움이 되는 경우도 있고 부가적인 정렬작업이 필요해 오히려 성능에 안좋은 영향을 미치는 경우도 있어 잘 고려하여 적용해야한다.