Loading...
MySQL 9.5 Reference Manual 9.5의 10.9.2 Switchable Optimizations의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
optimizer_switch 시스템 변수는 옵티마이저 동작을 제어할 수 있도록 해 줍니다. 이 값은 플래그들의 집합이며, 각각의 플래그는 해당 옵티마이저 동작이 활성화되었는지 비활성화되었는지를 나타내기 위해 on 또는 off 값을 가집니다. 이 변수는 전역 값과 세션 값을 가지며 런타임에 변경할 수 있습니다. 전역 기본값은 서버 시작 시 설정할 수 있습니다.
현재 옵티마이저 플래그 집합을 확인하려면 변수 값을 조회합니다:
1mysql> SELECT @@optimizer_switch\G 2*************************** 1. row *************************** 3@@optimizer_switch: index_merge=on,index_merge_union=on, 4 index_merge_sort_union=on,index_merge_intersection=on, 5 engine_condition_pushdown=on,index_condition_pushdown=on, 6 mrr=on,mrr_cost_based=on,block_nested_loop=on, 7 batched_key_access=off,materialization=on,semijoin=on, 8 loosescan=on,firstmatch=on,duplicateweedout=on, 9 subquery_materialization_cost_based=on, 10 use_index_extensions=on,condition_fanout_filter=on, 11 derived_merge=on,use_invisible_indexes=off,skip_scan=on, 12 hash_join=on,subquery_to_derived=off, 13 prefer_ordering_index=on,hypergraph_optimizer=off, 14 derived_condition_pushdown=on,hash_set_operations=on 151 row in set (0.00 sec)
optimizer_switch 값을 변경하려면, 하나 이상의 명령을 쉼표로 구분한 리스트로 된 값을 할당합니다:
1SET [GLOBAL|SESSION] optimizer_switch='command[,command]...';
각 command 값은 다음 표에 나와 있는 형식 중 하나여야 합니다.
| Command Syntax | Meaning |
|---|---|
default | 모든 옵티마이저 최적화를 기본값으로 리셋 |
opt_name=default | 지정된 옵티마이저 최적화를 기본값으로 설정 |
opt_name=off | 지정된 옵티마이저 최적화 비활성화 |
opt_name=on | 지정된 옵티마이저 최적화 활성화 |
값 안에서 명령들의 순서는 중요하지 않지만, 존재하는 경우 default 명령이 먼저 실행됩니다. opt_name 플래그를 default로 설정하면 해당 플래그는 기본값인 on 또는 off 중 하나로 설정됩니다. 하나의 opt_name 을 값 안에서 둘 이상 지정하는 것은 허용되지 않으며 오류를 발생시킵니다. 값에 오류가 있으면 할당이 오류와 함께 실패하며, optimizer_switch 값은 변경되지 않은 상태로 유지됩니다.
다음 목록은 허용되는 opt_name 플래그 이름을 최적화 전략별로 그룹화하여 설명합니다:
Batched Key Access Flags
batched_key_access
(기본값 off)
BKA 조인 알고리즘 사용을 제어합니다.
batched_key_access를 on으로 설정했을 때 효과를 가지려면, mrr 플래그도 on이어야 합니다. 현재 MRR에 대한 비용 추정은 너무 보수적입니다. 따라서 BKA가 사용되려면 mrr_cost_based도 off여야 합니다.
자세한 내용은 Section 10.2.1.12, “Block Nested-Loop and Batched Key Access Joins”를 참조하십시오.
Block Nested-Loop Flags
block_nested_loop
(기본값 on)
자세한 내용은 Section 10.2.1.12, “Block Nested-Loop and Batched Key Access Joins”를 참조하십시오.
Condition Filtering Flags
condition_fanout_filter
(기본값 on)
조건 필터링 사용을 제어합니다.
자세한 내용은 Section 10.2.1.13, “Condition Filtering”를 참조하십시오.
Derived Condition Pushdown Flags
derived_condition_pushdown
(기본값 on)
파생 조건 푸시다운을 제어합니다.
자세한 내용은 Section 10.2.2.5, “Derived Condition Pushdown Optimization”를 참조하십시오.
Derived Table Merging Flags
derived_merge (기본값
on)
파생 테이블과 뷰를 외부 쿼리 블록으로 머지하는 것을 제어합니다.
derived_merge 플래그는 옵티마이저가 파생 테이블, 뷰 참조, 공통 테이블 식을 외부 쿼리 블록으로 머지하려고 시도할지 여부를 제어하며, 다른 규칙이 머지를 방해하지 않는다고 가정합니다. 예를 들어, 뷰에 대한 ALGORITHM 지시문은 derived_merge 설정보다 우선합니다. 기본적으로 이 플래그는 머지를 활성화하기 위해 on입니다.
자세한 내용은 Section 10.2.2.4, “Optimizing Derived Tables, View References, and Common Table Expressions with Merging or Materialization”를 참조하십시오.
Engine Condition Pushdown Flags
engine_condition_pushdown
(기본값 on)
스토리지 엔진 조건 푸시다운을 제어합니다.
자세한 내용은 Section 10.2.1.5, “Engine Condition Pushdown Optimization”를 참조하십시오.
Hash Join Flags
hash_join (기본값
on)
MySQL 9.5에서는 효과가 없습니다. 대신 block_nested_loop 플래그를 사용하십시오.
자세한 내용은 Section 10.2.1.4, “Hash Join Optimization”를 참조하십시오.
Index Condition Pushdown Flags
index_condition_pushdown
(기본값 on)
인덱스 조건 푸시다운을 제어합니다.
자세한 내용은 Section 10.2.1.6, “Index Condition Pushdown Optimization”를 참조하십시오.
Index Extensions Flags
use_index_extensions
(기본값 on)
인덱스 확장 사용을 제어합니다.
자세한 내용은 Section 10.3.10, “Use of Index Extensions”를 참조하십시오.
Index Merge Flags
index_merge (기본값
on)
모든 인덱스 머지 최적화를 제어합니다.
index_merge_intersection
(기본값 on)
인덱스 머지 인터섹션 액세스 최적화를 제어합니다.
index_merge_sort_union
(기본값 on)
인덱스 머지 소트-유니언 액세스 최적화를 제어합니다.
index_merge_union
(기본값 on)
인덱스 머지 유니언 액세스 최적화를 제어합니다.
자세한 내용은 Section 10.2.1.3, “Index Merge Optimization”를 참조하십시오.
Index Visibility Flags
use_invisible_indexes
(기본값 off)
invisible 인덱스 사용을 제어합니다.
자세한 내용은 Section 10.3.12, “Invisible Indexes”를 참조하십시오.
Limit Optimization Flags
prefer_ordering_index
(기본값 on)
LIMIT 절이 있는 ORDER BY 또는
GROUP BY가 있는 쿼리의 경우, 옵티마이저가 unordered 인덱스, filesort, 기타 다른 최적화 대신 ordered 인덱스를 사용하려고 시도할지 여부를 제어합니다. 옵티마이저가 이 최적화를 사용하면 쿼리 실행이 더 빠를 것이라고 판단하는 경우, 기본적으로 이 최적화가 수행됩니다.
데이터 분포가 항상 어느 정도 균일하다는 가정 등으로 인해, 이 결정 알고리즘이 모든 가능한 경우를 처리할 수 있는 것은 아니므로, 이 최적화가 바람직하지 않은 경우도 있습니다. 이 최적화는 prefer_ordering_index 플래그를 off로 설정하여 비활성화할 수 있습니다.
자세한 내용과 예제는 Section 10.2.1.19, “LIMIT Query Optimization”를 참조하십시오.
Multi-Range Read Flags
mrr (기본값
on)
멀티 레인지 읽기 전략을 제어합니다.
mrr_cost_based
(기본값 on)
mrr=on인 경우 비용 기반 MRR 사용을 제어합니다.
자세한 내용은 Section 10.2.1.11, “Multi-Range Read Optimization”를 참조하십시오.
Semijoin Flags
duplicateweedout
(기본값 on)
세미조인 Duplicate Weedout 전략을 제어합니다.
firstmatch (기본값
on)
세미조인 FirstMatch 전략을 제어합니다.
loosescan (기본값
on)
세미조인 LooseScan 전략을 제어합니다 (GROUP BY에 대한 느슨한 인덱스 스캔과 혼동하지 마십시오).
semijoin (기본값
on)
모든 세미조인 전략을 제어합니다.
이는 안티조인 최적화에도 적용됩니다.
semijoin,
firstmatch,
loosescan,
duplicateweedout 플래그는 세미조인 전략에 대한 제어를 가능하게 합니다. semijoin 플래그는 세미조인 사용 여부를 제어합니다. 이것이 on이면, firstmatch 및 loosescan 플래그를 사용해 허용되는 세미조인 전략을 더 세밀하게 제어할 수 있습니다.
duplicateweedout 세미조인 전략이 비활성화된 경우, 다른 적용 가능한 모든 전략이 비활성화된 경우를 제외하고 이 전략은 사용되지 않습니다.
semijoin과 materialization이 모두 on이면, 해당되는 경우 세미조인에서도 머티리얼라이제이션이 사용됩니다. 이 플래그들은 기본적으로 on입니다.
자세한 내용은 Optimizing IN and EXISTS Subquery Predicates with Semijoin Transformations을 참조하십시오.
Set Operations Flags
hash_set_operations
(기본값 on)
EXCEPT 및
INTERSECT가 포함된 집합 연산에 대해 해시 테이블 최적화를 활성화합니다(기본적으로 활성화됨). 그렇지 않으면, 이전 MySQL 버전과 마찬가지로 임시 테이블 기반 중복 제거가 사용됩니다.
이 최적화에서 해싱에 사용하는 메모리 양은 set_operations_buffer_size 시스템 변수로 제어할 수 있습니다. 이 값을 증가시키면 일반적으로 이러한 연산을 사용하는 문장의 실행 시간이 더 빨라집니다.
Skip Scan Flags
skip_scan (기본값
on)
Skip Scan 액세스 방식 사용을 제어합니다.
자세한 내용은 Skip Scan Range Access Method를 참조하십시오.
Subquery Materialization Flags
materialization
(기본값 on)
머티리얼라이제이션(세미조인 머티리얼라이제이션 포함)을 제어합니다.
subquery_materialization_cost_based
(기본값 on)
비용 기반 머티리얼라이제이션 선택을 사용합니다.
materialization 플래그는 서브쿼리 머티리얼라이제이션 사용 여부를 제어합니다. semijoin과 materialization이 모두 on이면, 해당되는 경우 세미조인에서도 머티리얼라이제이션이 사용됩니다. 이 플래그들은 기본적으로 on입니다.
subquery_materialization_cost_based 플래그는 서브쿼리 머티리얼라이제이션과
IN-to-EXISTS 서브쿼리 변환 간 선택에 대한 제어를 가능하게 합니다. 플래그가 기본값인 on이면, 옵티마이저는 어느 방법이든 사용할 수 있는 경우 서브쿼리 머티리얼라이제이션과
IN-to-EXISTS 서브쿼리 변환 사이에서 비용 기반 선택을 수행합니다. 플래그가 off이면, 옵티마이저는
IN-to-EXISTS 서브쿼리 변환보다 서브쿼리 머티리얼라이제이션을 선택합니다.
자세한 내용은 Section 10.2.2, “Optimizing Subqueries, Derived Tables, View References, and Common Table Expressions”를 참조하십시오.
Subquery Transformation Flags
subquery_to_derived
(기본값 off)
옵티마이저는 많은 경우 SELECT, WHERE, JOIN, HAVING 절에 있는 스칼라 서브쿼리를 파생 테이블에 대한 left outer join으로 변환할 수 있습니다. (파생 테이블의 null 가능성에 따라, 이는 때때로 inner join으로 더 단순화될 수 있습니다.) 이 작업은 다음 조건을 만족하는 서브쿼리에 대해 수행될 수 있습니다:
RAND()와 같은 비결정적 함수(nondeterministic function)를 사용하지 않습니다.이 최적화는 또한 GROUP BY를 포함하지 않는, IN, NOT IN, EXISTS, NOT EXISTS의 인수인 테이블 서브쿼리에도 적용될 수 있습니다. 또한 많은 경우 SELECT 또는 WHERE 절에서 (ANY 또는 ALL과의 비교와 같은) 일반 quantified 비교 프레디컷에 대해서도 적용될 수 있습니다. 자세한 내용은 Section 10.2.2.6, “Optimizing ANY and ALL Subqueries”를 참조하십시오.
이 플래그의 기본값은 off입니다. 대부분의 경우, 이 최적화를 활성화해도 성능 향상은 눈에 띄지 않으며(많은 경우 쿼리가 더 느리게 실행될 수도 있습니다), 다만 서브쿼리 실행이 느릴 때 특정 상황에서 이 최적화를 활성화하면 유용할 수 있습니다. 이 최적화는 subquery_to_derived 플래그를 on으로 설정하여 활성화할 수 있습니다.
다음은 스칼라 서브쿼리를 사용하는 예입니다:
1d 2mysql> CREATE TABLE t1(a INT); 3 4mysql> CREATE TABLE t2(a INT); 5 6mysql> INSERT INTO t1 VALUES ROW(1), ROW(2), ROW(3), ROW(4); 7 8mysql> INSERT INTO t2 VALUES ROW(1), ROW(2); 9 10mysql> SELECT * FROM t1 11 -> WHERE t1.a > (SELECT COUNT(a) FROM t2); 12+------+ 13| a | 14+------+ 15| 3 | 16| 4 | 17+------+ 18 19mysql> SELECT @@optimizer_switch LIKE '%subquery_to_derived=off%'; 20+-----------------------------------------------------+ 21| @@optimizer_switch LIKE '%subquery_to_derived=off%' | 22+-----------------------------------------------------+ 23| 1 | 24+-----------------------------------------------------+ 25 26mysql> EXPLAIN SELECT * FROM t1 WHERE t1.a > (SELECT COUNT(a) FROM t2)\G 27*************************** 1. row *************************** 28 id: 1 29 select_type: PRIMARY 30 table: t1 31 partitions: NULL 32 type: ALL 33possible_keys: NULL 34 key: NULL 35 key_len: NULL 36 ref: NULL 37 rows: 4 38 filtered: 33.33 39 Extra: Using where 40*************************** 2. row *************************** 41 id: 2 42 select_type: SUBQUERY 43 table: t2 44 partitions: NULL 45 type: ALL 46possible_keys: NULL 47 key: NULL 48 key_len: NULL 49 ref: NULL 50 rows: 2 51 filtered: 100.00 52 Extra: NULL 53 54mysql> SET @@optimizer_switch='subquery_to_derived=on'; 55 56mysql> SELECT @@optimizer_switch LIKE '%subquery_to_derived=off%'; 57+-----------------------------------------------------+ 58| @@optimizer_switch LIKE '%subquery_to_derived=off%' | 59+-----------------------------------------------------+ 60| 0 | 61+-----------------------------------------------------+ 62 63mysql> SELECT @@optimizer_switch LIKE '%subquery_to_derived=on%'; 64+----------------------------------------------------+ 65| @@optimizer_switch LIKE '%subquery_to_derived=on%' | 66+----------------------------------------------------+ 67| 1 | 68+----------------------------------------------------+ 69 70mysql> EXPLAIN SELECT * FROM t1 WHERE t1.a > (SELECT COUNT(a) FROM t2)\G 71*************************** 1. row *************************** 72 id: 1 73 select_type: PRIMARY 74 table: <derived2> 75 partitions: NULL 76 type: ALL 77possible_keys: NULL 78 key: NULL 79 key_len: NULL 80 ref: NULL 81 rows: 1 82 filtered: 100.00 83 Extra: NULL 84*************************** 2. row *************************** 85 id: 1 86 select_type: PRIMARY 87 table: t1 88 partitions: NULL 89 type: ALL 90possible_keys: NULL 91 key: NULL 92 key_len: NULL 93 ref: NULL 94 rows: 4 95 filtered: 33.33 96 Extra: Using where; Using join buffer (hash join) 97*************************** 3. row *************************** 98 id: 2 99 select_type: DERIVED 100 table: t2 101 partitions: NULL 102 type: ALL 103possible_keys: NULL 104 key: NULL 105 key_len: NULL 106 ref: NULL 107 rows: 2 108 filtered: 100.00 109 Extra: NULL
두 번째 EXPLAIN 문을 실행한 직후에 SHOW WARNINGS를 실행해 보면, 최적화가 활성화된 상태에서
SELECT * FROM t1 WHERE t1.a > (SELECT COUNT(a) FROM t2) 쿼리는 다음에 표시된 것과 비슷한 형태로 리라이트된다는 것을 볼 수 있습니다:
1SELECT t1.a FROM t1 2 JOIN ( SELECT COUNT(t2.a) AS c FROM t2 ) AS d 3 WHERE t1.a > d.c;
다음은 IN (subquery)를 사용하는 쿼리의 예입니다:
1mysql> DROP TABLE IF EXISTS t1, t2; 2 3mysql> CREATE TABLE t1 (a INT, b INT); 4mysql> CREATE TABLE t2 (a INT, b INT); 5 6mysql> INSERT INTO t1 VALUES ROW(1,10), ROW(2,20), ROW(3,30); 7mysql> INSERT INTO t2 8 -> VALUES ROW(1,10), ROW(2,20), ROW(3,30), ROW(1,110), ROW(2,120), ROW(3,130); 9 10mysql> SELECT * FROM t1 11 -> WHERE t1.b < 0 12 -> OR 13 -> t1.a IN (SELECT t2.a + 1 FROM t2); 14+------+------+ 15| a | b | 16+------+------+ 17| 2 | 20 | 18| 3 | 30 | 19+------+------+ 20 21mysql> SET @@optimizer_switch="subquery_to_derived=off"; 22 23mysql> EXPLAIN SELECT * FROM t1 24 -> WHERE t1.b < 0 25 -> OR 26 -> t1.a IN (SELECT t2.a + 1 FROM t2)\G 27*************************** 1. row *************************** 28 id: 1 29 select_type: PRIMARY 30 table: t1 31 partitions: NULL 32 type: ALL 33possible_keys: NULL 34 key: NULL 35 key_len: NULL 36 ref: NULL 37 rows: 3 38 filtered: 100.00 39 Extra: Using where 40*************************** 2. row *************************** 41 id: 2 42 select_type: DEPENDENT SUBQUERY 43 table: t2 44 partitions: NULL 45 type: ALL 46possible_keys: NULL 47 key: NULL 48 key_len: NULL 49 ref: NULL 50 rows: 6 51 filtered: 100.00 52 Extra: Using where 53 54mysql> SET @@optimizer_switch="subquery_to_derived=on"; 55 56mysql> EXPLAIN SELECT * FROM t1 57 -> WHERE t1.b < 0 58 -> OR 59 -> t1.a IN (SELECT t2.a + 1 FROM t2)\G 60*************************** 1. row *************************** 61 id: 1 62 select_type: PRIMARY 63 table: t1 64 partitions: NULL 65 type: ALL 66possible_keys: NULL 67 key: NULL 68 key_len: NULL 69 ref: NULL 70 rows: 3 71 filtered: 100.00 72 Extra: NULL 73*************************** 2. row *************************** 74 id: 1 75 select_type: PRIMARY 76 table: <derived2> 77 partitions: NULL 78 type: ref 79possible_keys: <auto_key0> 80 key: <auto_key0> 81 key_len: 9 82 ref: std2.t1.a 83 rows: 2 84 filtered: 100.00 85 Extra: Using where; Using index 86*************************** 3. row *************************** 87 id: 2 88 select_type: DERIVED 89 table: t2 90 partitions: NULL 91 type: ALL 92possible_keys: NULL 93 key: NULL 94 key_len: NULL 95 ref: NULL 96 rows: 6 97 filtered: 100.00 98 Extra: Using temporary
이 쿼리에 대해 EXPLAIN을 실행한 후 SHOW WARNINGS 결과를 확인하고 단순화해 보면, subquery_to_derived 플래그가 활성화된 경우 SELECT * FROM t1 WHERE t1.b < 0 OR t1.a IN (SELECT t2.a + 1 FROM t2)가 다음과 비슷한 형태로 리라이트되었다는 것을 알 수 있습니다:
1SELECT a, b FROM t1 2 LEFT JOIN (SELECT DISTINCT a + 1 AS e FROM t2) d 3 ON t1.a = d.e 4 WHERE t1.b < 0 5 OR 6 d.e IS NOT NULL;
다음은 EXISTS (subquery)를 사용하는 쿼리의 예로, 앞선 예제와 동일한 테이블과 데이터를 사용합니다:
1mysql> SELECT * FROM t1 2 -> WHERE t1.b < 0 3 -> OR 4 -> EXISTS(SELECT * FROM t2 WHERE t2.a = t1.a + 1); 5+------+------+ 6| a | b | 7+------+------+ 8| 1 | 10 | 9| 2 | 20 | 10+------+------+ 11 12mysql> SET @@optimizer_switch="subquery_to_derived=off"; 13 14mysql> EXPLAIN SELECT * FROM t1 15 -> WHERE t1.b < 0 16 -> OR 17 -> EXISTS(SELECT * FROM t2 WHERE t2.a = t1.a + 1)\G 18*************************** 1. row *************************** 19 id: 1 20 select_type: PRIMARY 21 table: t1 22 partitions: NULL 23 type: ALL 24possible_keys: NULL 25 key: NULL 26 key_len: NULL 27 ref: NULL 28 rows: 3 29 filtered: 100.00 30 Extra: Using where 31*************************** 2. row *************************** 32 id: 2 33 select_type: DEPENDENT SUBQUERY 34 table: t2 35 partitions: NULL 36 type: ALL 37possible_keys: NULL 38 key: NULL 39 key_len: NULL 40 ref: NULL 41 rows: 6 42 filtered: 16.67 43 Extra: Using where 44 45mysql> SET @@optimizer_switch="subquery_to_derived=on"; 46 47mysql> EXPLAIN SELECT * FROM t1 48 -> WHERE t1.b < 0 49 -> OR 50 -> EXISTS(SELECT * FROM t2 WHERE t2.a = t1.a + 1)\G 51*************************** 1. row *************************** 52 id: 1 53 select_type: PRIMARY 54 table: t1 55 partitions: NULL 56 type: ALL 57possible_keys: NULL 58 key: NULL 59 key_len: NULL 60 ref: NULL 61 rows: 3 62 filtered: 100.00 63 Extra: NULL 64*************************** 2. row *************************** 65 id: 1 66 select_type: PRIMARY 67 table: <derived2> 68 partitions: NULL 69 type: ALL 70possible_keys: NULL 71 key: NULL 72 key_len: NULL 73 ref: NULL 74 rows: 6 75 filtered: 100.00 76 Extra: Using where; Using join buffer (hash join) 77*************************** 3. row *************************** 78 id: 2 79 select_type: DERIVED 80 table: t2 81 partitions: NULL 82 type: ALL 83possible_keys: NULL 84 key: NULL 85 key_len: NULL 86 ref: NULL 87 rows: 6 88 filtered: 100.00 89 Extra: Using temporary
SELECT * FROM t1 WHERE t1.b < 0 OR EXISTS(SELECT * FROM t2 WHERE t2.a = t1.a + 1) 쿼리에 대해 EXPLAIN을 실행한 후, subquery_to_derived이 활성화된 상태에서 SHOW WARNINGS를 실행하고 결과의 두 번째 row를 단순화해 보면, 다음과 비슷한 형태로 리라이트되었다는 것을 볼 수 있습니다:
1SELECT a, b FROM t1 2LEFT JOIN (SELECT DISTINCT 1 AS e1, t2.a AS e2 FROM t2) d 3ON t1.a + 1 = d.e2 4WHERE t1.b < 0 5 OR 6 d.e1 IS NOT NULL;
자세한 내용은 Section 10.2.2.4, “Optimizing Derived Tables, View References, and Common Table Expressions with Merging or Materialization”, Section 10.2.1.19, “LIMIT Query Optimization”, Optimizing IN and EXISTS Subquery Predicates with Semijoin Transformations도 참조하십시오.
optimizer_switch에 값을 할당할 때, 명시되지 않은 플래그들은 현재 값을 유지합니다. 이를 통해 다른 동작에 영향을 주지 않고 하나의 문장에서 특정 옵티마이저 동작만 활성화 또는 비활성화할 수 있습니다. 이 문장은 다른 옵티마이저 플래그가 무엇인지, 그 값이 무엇인지에 의존하지 않습니다. 모든 인덱스 머지 최적화가 활성화되어 있다고 가정합니다:
1mysql> SELECT @@optimizer_switch\G 2*************************** 1. row *************************** 3@@optimizer_switch: index_merge=on,index_merge_union=on, 4 index_merge_sort_union=on,index_merge_intersection=on, 5 engine_condition_pushdown=on,index_condition_pushdown=on, 6 mrr=on,mrr_cost_based=on,block_nested_loop=on, 7 batched_key_access=off,materialization=on,semijoin=on, 8 loosescan=on, firstmatch=on, 9 subquery_materialization_cost_based=on, 10 use_index_extensions=on,condition_fanout_filter=on, 11 derived_merge=on,use_invisible_indexes=off,skip_scan=on, 12 hash_join=on,subquery_to_derived=off, 13 prefer_ordering_index=on
서버가 특정 쿼리에 대해 인덱스 머지 유니언 또는 인덱스 머지 소트-유니언 액세스 방식을 사용 중이고, 이러한 방식 없이 옵티마이저가 더 잘 동작할 수 있는지 확인하고자 한다면, 변수 값을 다음과 같이 설정합니다:
1mysql> SET optimizer_switch='index_merge_union=off,index_merge_sort_union=off'; 2 3mysql> SELECT @@optimizer_switch\G 4*************************** 1. row *************************** 5@@optimizer_switch: index_merge=on,index_merge_union=off, 6 index_merge_sort_union=off,index_merge_intersection=on, 7 engine_condition_pushdown=on,index_condition_pushdown=on, 8 mrr=on,mrr_cost_based=on,block_nested_loop=on, 9 batched_key_access=off,materialization=on,semijoin=on, 10 loosescan=on, firstmatch=on, 11 subquery_materialization_cost_based=on, 12 use_index_extensions=on,condition_fanout_filter=on, 13 derived_merge=on,use_invisible_indexes=off,skip_scan=on, 14 hash_join=on,subquery_to_derived=off, 15 prefer_ordering_index=on
10.9.1 Controlling Query Plan Evaluation
10.9.3 Optimizer Hints