optimizer_switch
시스템 변수를 이용해서 제어한다.optimizer_switch
시스템 변수에는 여러 개의 옵션을 세트로 묶어서 설정하는 방식으로 사용한다.옵션에 대한 자세한 설명은 다음 글에서 각각 설명한다.
옵티마이저 스위치 이름 | 기본값 | 설명 |
---|---|---|
batched_key_access | off | BKA 조인 알고리즘을 사용할지 여부 설정 |
block_nested_loop | on | Block Nested Loop 조인 알고리즘을 사용할지 여부 설정 |
engine_condition_pushdown | on | Engine Condition Pushdown 기능을 사용할지 여부 설정 |
index_condition_pushdown | on | Index Condition Pushdown 기능을 사용할지 여부 설정 |
use_index_extensions | on | Index Extension 최적화를 사용할지 여부 설정 |
index_merge | on | Index Merge 최적화를 사용할지 여부 설정 |
index_merge_intersection | on | Index Merge Intersection 최적화를 사용할지 여부 설정 |
index_merge_sort_union | on | Index Merge Sort Union 최적화를 사용할지 여부 설정 |
index_merge_union | on | Index Merge Union 최적화를 사용할지 여부 설정 |
mrr | on | MRR 최적화를 사용할지 여부 설정 |
mrr_cost_based | on | 비용 기반의 MRR 최적화를 사용할지 여부 설정 |
semijoin | on | 세미 조인 최적화를 사용할지 여부 설정 |
firstmatch | on | FirstMatch 세미 조인 최적화를 사용할지 여부 설정 |
loosescan | on | LooseScan 세미 조인 최적화를 사용할지 여부 설정 |
materialization | on | Materialization 최적화를 사용할지 여부 설정 (Materialization 세미 조인 최적화 포함) |
subquery_materialization_cost_based | on | 비용 기반의 Materialization 최적화를 사용할지 여부 설정 |
-- MySQL 서버 전체적으로 옵티마이저 스위치 설정
SET GLOBAL optimizer_switch='index_merge=on,index_merge_union=on,...';
-- 현재 커넥션의 옵티마이저 스위치만 설정
SET SESSION optimizer_switch='index_merge=on,index_merge_union=on,...';
-- 현재 쿼리에만 옵티마이저 스위치 설정
SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off') */ 1;
💡 SET_VAR 사용법
SET_VAR는 (단일) 명령문이 실행되는 동안 시스템 변수의 세션 값을 일시적으로 설정하는 힌트 구문이다.
var_name
: 세션 값이 있는 시스템 변수의 이름value
: 할당할 값SET_VAR(var_name = value)
MySQL에서
/*+*/
는 쿼리 힌트를 지정하는 데 사용한다. 따라서, 다음과 같이 사용하면 된다.SELECT /*+ SET_VAR(sort_buffer_size = 16M) */ name FROM people ORDER BY name; INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2); SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off') */ 1;
출처: https://dev.mysql.com/doc/refman/8.3/en/optimizer-hints.html#optimizer-hints-set-var, AI Gemini
💡 오타?
서적에서, 또 다른 예시를 들면서 테이블이 20개라면 개가 된다고 설명했다.그런데 이이며, 3628800개가 되는 건 이다.
뒤에서 테이블이 10개일 때를 말하며 실행 계획 시간을 설명하는 걸 보면 단순 오타인 듯하다.
optimizer_search_depth
시스템 설정 변수에 설정된 값에 따라 조인 최적화의 비용이 상당히 줄어들 수 있다.optimizer_search_depth
시스템 설정 변수에 정의된 개수의 테이블로 가능한 조인 조합을 생성한다.optimizer_search_depth
시스템 설정 변수에 정의된 개수의 테이블로 가능한 조인 조합을 생성한다.전체 4개의 테이블()이고,
optimizer_search_depth=2
라고 가정한다.SELECT * FROM t1, t2, t3, t4;
전체 4개의 테이블 중에서 2개의 테이블로 가능한 조인 조합을 생성한다.
optimizer_search_depth
시스템 설정 변수에 정의된 개수는 2개(1)번에서 생성된 조인 조합 중에서 최소 비용의 실행 계획 하나를 선정한다.
T3 → T2
선택(2)번에서 선정된 실행 계획의 첫 번째 테이블을 “부분 실행 계획(실행 계획 완료 대상)”의 첫 번째 테이블로 선정한다.
(3)번에서 선택된 T3
테이블을 제외한, 전체 3개의 테이블에서 다시 2개의 테이블로 가능한 조인 조합을 생성한다.
생성된 조인 조합들을 하나씩 “부분 실행 계획”에 대입해 실행 비용을 계산한다.
(5)번의 비용 계산 결과, 최적의 실행 계획에서 두 번째 테이블을 “부분 실행 계획”의 두 번째 테이블로 선정한다.
T4 → T2
선택앞서 선택된 T3
, T4
테이블을 제외한 전체 2개의 테이블에서 다시 2개의 테이블로 가능한 조인 조합을 생성한다.
생성된 조인 조합들을 하나씩 “부분 실행 계획”에 대입해 실행 비용을 계산한다.
(8)번의 비용 계산 결과, 최적의 실행 계획에서 두 번째 테이블을 “부분 실행 계획”의 세 번째 테이블로 선정한다.
T2 → T1
선택남은 테이블이 T1
하나이므로, “부분 실행 계획”에 테이블의 조인 순서를 기록한다.
최종적으로 “부분 실행 계획”이 테이블의 조인 순서로 결정된다.
optimizer_prune_lebel
과 optimizer_search_depth
가 제공된다.optimizer_search_depth
optimizer_prune_lebel
MySQL 옵티마이저 힌트 문서
AI Gemini