View Source

h2. 개요
h4. 쿼리 실행 절차

||구분||단계||실행 주체||결과물|
|1|SQL 파싱|SQL 파서(MariaDB 엔진)|SQL 파스 트리|
|2|최적화 및 실행 계획 수립|옵티마이저(MariaDB 엔진)|실행 계획|
|3|SQL 실행|스토리지 엔진 + MariaDB 엔진|쿼리 결과값|

\\

h4. 옵티마이저의 종류

|규칙 기반 최적화
(RBO:Rule-based optimizer)| 옵티마이저에 내장된 우선순위에 따라 실행 계획을 수립|
|비용 기반 최적화
(CBO:Cost-based optimizer)| 부하 정보와 통계 정보를 이용해 각 실행 계획별 비용을 산출하여 최소 비용의 실행 계획을 선택|

\\

h4. MariaDB 10.0의 통계 정보
* MariaDB 10.0부터 통합 통계 정보 관리 기능을 제공
* 인덱스 컬럼 외 컬럼의 통계 정보 관리 가능
* 통계 정보를 영구적으로 사용 가능: 통계 정보를 별도로 백업해 복구해서 사용할 수 있음
* 관리자가 직접 통계 정보 변경 가능

\\

h6. 통합 통계 테이블

||table_stat|컬럼|의미|
| |db_name|대상 테이블이 속한 데이터베이스 명|
| |table_name|대상 테이블의 이름|
| |cardianlity|테이블의 레코드 건수|
||column_stat|컬럼|의미|
| |db_name|대상 테이블이 속한 데이터베이스 명|
| |table_name|대상 테이블의 이름|
| |column_name|대상 컬럼 이름|
| |min_value|해당 컬럼의 최소값(정수 타입도 문자열 포맷으로 저장)|
| |max_value|해당 컬럼의 최대값(정수 타입도 문자열 포맷으로 저장)|
| |nulls_ratio|NULL 값의 비율(0:NULL 없음, 0.5:NULL값을 가진 레코드가 50%, 1: 모든 레코드가 NULL)|
| |avg_length|컬럼 값의 평균 바이트 수|
| |avg_frequency|중복된 값을 가진 평균 레코드의 수(1:중복된 값 없음)|
||index_stat|컬럼|의미|
| |db_name|대상 테이블이 속한 데이터베이스 명|
| |table_name|대상 테이블의 이름|
| |index_name|대상 인덱스의 이름|
| |prefix_arity|인덱스 컬럼 순번|
| |avg_frequency|중복된 값을 가진 평균 레코드의 수(1:중복된 값 없음)|

\\

h6. 통계 파라미터

||파라미터||값||내용|
|use_stat_tables|never|MySQL 5.6의 통계 정보 관리 방식과 동일, 통합 통계 테이블에는 통계를 수집하지 않음|
|use_stat_tables|complementary|각 스토리지 엔진이 제공하는 통계정보를 우선적으로 사용하되 스토리지 엔진이 제공하는 정보가 부족하거나 없는 경우에는 MariaDB의 통합 정보가 사용됨|
|use_stat_tables|preferably|각 스토리지 엔진별로 관리되는 통계 정보보다 MariaDB의 통합 통계 정보를 우선해서 사용|

{code:sql}
create table tabl_recalc as select * from employees;

insert into tabl_recalc select * from employees;

MariaDB [(none)]> show global variables like 'innodb_stats_auto_recalc';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_stats_auto_recalc | ON |
+--------------------------+-------+
1 row in set (0.00 sec)

MariaDB [employees]> select * from mysql.table_stats where table_name='tabl_recalc';
Empty set (0.00 sec)

MariaDB [employees]> select * from mysql.innodb_table_stats where table_name='tabl_recalc';
+---------------+-------------+---------------------+--------+----------------------+--------------------------+
| database_name | table_name | last_update | n_rows | clustered_index_size | sum_of_other_index_sizes |
+---------------+-------------+---------------------+--------+----------------------+--------------------------+
| employees | tabl_recalc | 2017-04-14 21:33:55 | 299439 | 1057 | 0 |
+---------------+-------------+---------------------+--------+----------------------+--------------------------+
1 row in set (0.00 sec)

MariaDB [employees]> show global variables like 'use_stat_tables';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| use_stat_tables | NEVER |
+-----------------+-------+
1 row in set (0.00 sec)

MariaDB [employees]> analyze table tabl_recalc;
+-----------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-----------------------+---------+----------+----------+
| employees.tabl_recalc | analyze | status | OK |
+-----------------------+---------+----------+----------+
1 row in set (0.01 sec)

MariaDB [employees]> select * from mysql.table_stats where table_name='tabl_recalc';
Empty set (0.00 sec)

MariaDB [employees]> SET SESSION use_stat_tables='COMPLEMENTARY';
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> analyze table tabl_recalc;
+-----------------------+---------+----------+-----------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------------------+---------+----------+-----------------------------------------+
| employees.tabl_recalc | analyze | status | Engine-independent statistics collected |
| employees.tabl_recalc | analyze | status | OK |
+-----------------------+---------+----------+-----------------------------------------+
2 rows in set (0.54 sec)

MariaDB [employees]> select * from mysql.table_stats where table_name='tabl_recalc';
+-----------+-------------+-------------+
| db_name | table_name | cardinality |
+-----------+-------------+-------------+
| employees | tabl_recalc | 300024 |
+-----------+-------------+-------------+
1 row in set (0.00 sec)
{code}

{info:title=통계 수집 시 주의 사항}
ANALYZE TABLE 명령이 실행되면 테이블을 풀 스캔하거나 인덱스 풀 스캔하여 통계 수집
마스터와 슬레이브 구조라면 슬레이브에서 통계 정보를 수집하여 마스터에 복사
{info}

\\

h6. 통계 생성 구문

||tbl 테이블, col1과 col2 컬럼, idx1과 idx2 인덱스에 대해서만 통계 정보 수집|
|analyze table tbl persistent for columns (col1, col2) indexes (idx1, idx2);|
||tbl 테이블, col1과 col2 컬럼에 대해서만 통계 수집|
|analyze table tbl persistent for columns (col1, col2) indexes ();|
||tbl 테이블, idx1, idx2 인덱스에 대해서만 통계 수집|
|analyze table tbl persistent for columns () indexes (idx1, idx2);|
||tbl 테이블에 대해서만 통계 수집|
|analyze table tbl persistent for columns () indexes ();|
||테이블, 모든 컬럼, 모든 인덱스의 통계 수집(=analyze table tbl; )|
|analyze table tbl persistent for all;|

\\

h4. 히스토그램 통계 정보

* 히스토그램: 컬럼 값의 분포도를 분석할 수 있는 통계 정보
* Height-Balanced Histogram 알고리즘 사용

{code:sql}
MariaDB [employees]> desc mysql.column_stats;
+---------------+-----------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------------------------+------+-----+---------+-------+
| db_name | varchar(64) | NO | PRI | NULL | |
| table_name | varchar(64) | NO | PRI | NULL | |
| column_name | varchar(64) | NO | PRI | NULL | |
| min_value | varbinary(255) | YES | | NULL | |
| max_value | varbinary(255) | YES | | NULL | |
| nulls_ratio | decimal(12,4) | YES | | NULL | |
| avg_length | decimal(12,4) | YES | | NULL | |
| avg_frequency | decimal(12,4) | YES | | NULL | |
| hist_size | tinyint(3) unsigned | YES | | NULL | |
| hist_type | enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') | YES | | NULL | |
| histogram | varbinary(255) | YES | | NULL | |
+---------------+-----------------------------------------+------+-----+---------+-------+
11 rows in set (0.00 sec)

--MariaDB에서 히스토그램 사용
MariaDB [employees]> set histogram_size=20;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> set use_stat_tables='preferably';
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> set histogram_type='double_prec_hb';
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> analyze table salaries;
+--------------------+---------+----------+-----------------------------------------+
| Table | Op | Msg_type | Msg_text |
+--------------------+---------+----------+-----------------------------------------+
| employees.salaries | analyze | status | Engine-independent statistics collected |
| employees.salaries | analyze | status | OK |
+--------------------+---------+----------+-----------------------------------------+
2 rows in set (8.28 sec)

MariaDB [employees]> select table_name, min_value, max_value, hist_size, hist_type,
-> decode_histogram(hist_type, histogram) as histogram
-> from mysql.column_stats
-> where table_name='salaries' and column_name='salary'\G
*************************** 1. row ***************************
table_name: salaries
min_value: 38623
max_value: 158220
hist_size: 20
hist_type: DOUBLE_PREC_HB
histogram: 0.04030,0.03436,0.03273,0.03198,0.03232,0.03375,0.03688,0.04285,0.05443,0.07974,0.58065 <<< 버킷최대값 / (최대값-최소값) * 216 (single_prec_hb:28)
1 row in set (0.00 sec)

MariaDB [employees]> set histogram_size=100;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> set use_stat_tables='preferably';
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> set histogram_type='double_prec_hb';
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> analyze table salaries;
+--------------------+---------+----------+-----------------------------------------+
| Table | Op | Msg_type | Msg_text |
+--------------------+---------+----------+-----------------------------------------+
| employees.salaries | analyze | status | Engine-independent statistics collected |
| employees.salaries | analyze | status | OK |
+--------------------+---------+----------+-----------------------------------------+
2 rows in set (7.94 sec)

MariaDB [employees]> set optimizer_use_condition_selectivity=4;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> explain extended select * from salaries where to_date <= '1989-03-01';
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | salaries | ALL | NULL | NULL | NULL | NULL | 2844047 | 5.88 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

MariaDB [employees]> select count(*), (2844047*0.0588) as expected_value from salaries where to_date <= '1989-03-01';
+----------+----------------+
| count(*) | expected_value |
+----------+----------------+
| 125536 | 167229.9636 |
+----------+----------------+
1 row in set (2.40 sec)

MariaDB [employees]> set histogram_size=200;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> analyze table salaries;
+--------------------+---------+----------+-----------------------------------------+
| Table | Op | Msg_type | Msg_text |
+--------------------+---------+----------+-----------------------------------------+
| employees.salaries | analyze | status | Engine-independent statistics collected |
| employees.salaries | analyze | status | OK |
+--------------------+---------+----------+-----------------------------------------+
2 rows in set (9.70 sec)

MariaDB [employees]> explain extended
-> select * from salaries where to_date <= '1989-03-01';
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | salaries | ALL | NULL | NULL | NULL | NULL | 2844047 | 4.95 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

MariaDB [employees]> select count(*), (2844047*0.0495) as expected_value from salaries where to_date <= '1989-03-01';
+----------+----------------+
| count(*) | expected_value |
+----------+----------------+
| 125536 | 140780.3265 |
+----------+----------------+
1 row in set (2.83 sec)
{code}

\\

h4. 조인 옵티마이저 옵션

* Exhaustive 검색: from절에 명시된 모든 테이블 조합에 대해서 실행 계획의 비용을 계산하여 최적의 조합 선택
* Heuristic 검색(Greedy 검색)

||구분||내용|
|1|전체 N개의 테이블 중에서 optimizer_search_depth 시스템 설정 변수에 정의된 개수의 테이블로 가능한 조인 조합을 생성|
|2|1번에서 생성된 조인 조합 중에서 최소 비용의 실행 계획 하나를 선정|
|3|2번에서 선정된 실행 계획의 첫 번째 테이블을 "부분 실행 계획"의 첫번째 테이블로 선정|
|4|전체 N-1개의 테이블 중에서(3번에서 선택된 테이블 제외) optimizer_search_depth 시스템 변수에 정의된 개수의 테이블로 가능한 조인 조합을 생성|
|5|4번에서 생성된 조인 조합들을 하나씩 3번에서 생성된 "부분 실행 계획"에 대입해서 실행 비용을 계산|
|6|5번의 비용 계산 결과, 가장 비용이 낮은 실행 계획을 골라서 그 중 두 번째 테이블을 3번에서 생성된 "부분 실행 계획"의 두 번째 테이블로 선정|
|7|남은 테이블이 모두 없어질 때까지 4~6번까지의 과정을 반복 실행하면서 "부분 실행 계획"에 테이블의 조인 순서를 기록|
|8|최종적으로 "부분 실행 계획"이 테이블의 조인 순서로 결정|

* optimizer_search_depth의 default 값: 64

{code:sql}
MariaDB [employees]> set session optimizer_prune_level=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> set session optimizer_search_depth=5;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> select * from tab01,tab02,tab03,tab04,tab05,tab06,tab07,tab08,tab09,tab10, tab11,tab12,tab13,tab14,tab15,tab16,tab17,tab18,tab19,tab20, tab21,tab22,tab23,tab24,tab25,tab26,tab27,tab28,tab29,tab30 where tab01.fd1=tab02.fd1 and tab02.fd1=tab03.fd2 and tab03.fd1=tab04.fd1 and tab04.fd2=tab05.fd2 and tab05.fd2=tab06.fd1 and tab06.fd2=tab07.fd2 and tab07.fd1=tab08.fd1 and tab08.fd1=tab09.fd2 and tab09.fd1=tab10.fd1 and tab10.fd2=tab11.fd2 and tab11.fd2=tab12.fd1 and tab12.fd2=tab13.fd2 and tab13.fd1=tab14.fd1 and tab14.fd1=tab15.fd2 and tab15.fd1=tab16.fd1 and tab16.fd2=tab17.fd2 and tab17.fd2=tab18.fd1 and tab18.fd2=tab19.fd2 and tab19.fd1=tab20.fd1 and tab20.fd1=tab21.fd2 and tab21.fd1=tab22.fd1 and tab22.fd2=tab23.fd2 and tab23.fd2=tab24.fd1 and tab24.fd2=tab25.fd2 and tab25.fd1=tab26.fd1 and tab26.fd1=tab27.fd2 and tab27.fd1=tab28.fd1 and tab28.fd2=tab29.fd2 and tab29.fd2=tab30.fd1;
(((결과 생략)))
2000 rows in set (0.09 sec)

MariaDB [employees]> set session optimizer_search_depth=64;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

MariaDB [employees]> reset query cache;
Query OK, 0 rows affected (0.00 sec)

MariaDB [employees]> select * from tab01,tab02,tab03,tab04,tab05,tab06,tab07,tab08,tab09,tab10, tab11,tab12,tab13,tab14,tab15,tab16,tab17,tab18,tab19,tab20, tab21,tab22,tab23,tab24,tab25,tab26,tab27,tab28,tab29,tab30 where tab01.fd1=tab02.fd1 and tab02.fd1=tab03.fd2 and tab03.fd1=tab04.fd1 and tab04.fd2=tab05.fd2 and tab05.fd2=tab06.fd1 and tab06.fd2=tab07.fd2 and tab07.fd1=tab08.fd1 and tab08.fd1=tab09.fd2 and tab09.fd1=tab10.fd1 and tab10.fd2=tab11.fd2 and tab11.fd2=tab12.fd1 and tab12.fd2=tab13.fd2 and tab13.fd1=tab14.fd1 and tab14.fd1=tab15.fd2 and tab15.fd1=tab16.fd1 and tab16.fd2=tab17.fd2 and tab17.fd2=tab18.fd1 and tab18.fd2=tab19.fd2 and tab19.fd1=tab20.fd1 and tab20.fd1=tab21.fd2 and tab21.fd1=tab22.fd1 and tab22.fd2=tab23.fd2 and tab23.fd2=tab24.fd1 and tab24.fd2=tab25.fd2 and tab25.fd1=tab26.fd1 and tab26.fd1=tab27.fd2 and tab27.fd1=tab28.fd1 and tab28.fd2=tab29.fd2 and tab29.fd2=tab30.fd1;
(((결과 생략)))
2000 rows in set (0.10 sec)
{code}

\\

h2. 실행 계획 분석

{code:sql}
MariaDB [employees]> explain
-> select e.emp_no, e.first_name, s.from_date, s.salary
-> from employees e, salaries s
-> where e.emp_no = s.emp_no
-> limit 10;
+------+-------------+-------+-------+---------------+--------------+---------+--------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+--------------+---------+--------------------+--------+-------------+
| 1 | SIMPLE | e | index | PRIMARY | ix_firstname | 16 | NULL | 299335 | Using index |
| 1 | SIMPLE | s | ref | PRIMARY | PRIMARY | 4 | employees.e.emp_no | 4 | |
+------+-------------+-------+-------+---------------+--------------+---------+--------------------+--------+-------------+
2 rows in set (0.00 sec)
{code}

* 레코드는 쿼리 문장에서 사용된 테이블의 개수만큼 출력(임시테이블 포함)
* 실행 순서는 위에서 아래로 순서대로 표시(union이나 상관 서브 쿼리와 같은 경우 순서대로 표시되지 않을 수 있음)
* id 컬럼의 값이 작을 수록 쿼리의 outer부분이거나 먼저 접근한 테이블, id 컬럼의 값이 클수록 쿼리의 inner부분 또는 나중에 접근한 테이블

\\

h4. id 컬럼

* 단위 select 쿼리별로 부여되는 식별자

{code:sql}
MariaDB [employees]> explain
-> select
-> ((select count(*) from employees) + (select count(*) from departments)) as total_count;
+------+-------------+-------------+-------+---------------+-------------+---------+------+--------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------+-------+---------------+-------------+---------+------+--------+----------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 3 | SUBQUERY | departments | index | NULL | PRIMARY | 4 | NULL | 9 | Using index |
| 2 | SUBQUERY | employees | index | NULL | ix_hiredate | 3 | NULL | 299335 | Using index |
+------+-------------+-------------+-------+---------------+-------------+---------+------+--------+----------------+
3 rows in set (0.00 sec)
{code}

\\

h4. select_type 컬럼

|SIMPLE|union이나 서브 쿼리를 사용하지 않는 단순한 select 쿼리, 실행계획에서 SIMPLE은 하나만 존재하며 일반적으로 제일 바깥 select쿼리가 SIMPLE로 표시|
|PRIMARY|union이나 서브 쿼리를 가지는 select 쿼리의 실행 계획에서 가장 바깥쪽(outer)에 있는 단위 쿼리, 실행계획에서 하나만 존재하며 일반적으로 제일 바깥 select쿼리가 PRIMARY로 표시|
|UNION|union으로 결합하는 단위 select쿼리 가운데 첫 번째를 제외한 두 번째 이후 단위 select 쿼리|
|DEPENDENT UNION|union이나 union all로 결합된 단위 쿼리가 외부의 의해 영향을 받는 쿼리|
|UNION RESULT|union 결과 테이블을 의미, id 값이 부여되지 않음|
|SUBQUERY|from절 이외에서 사용되는 서브 쿼리만을 의미|
|DEPENDENT SUBQUERY|서브 쿼리가 바깥쪽(outer) select 쿼리에서 정의된 컬럼을 사용하는 경우|
|DERIVED|단위 select쿼리의 실행 결과를 메모리나 디스크에 임시 테이블을 생성하는 것을 의미, 서브 쿼리가 from절에 사용된 경우|
|UNCACHEABLE SUBQUERY|서브 쿼리 결과를 내부적인 캐시 공간에 저장되지 못하는 경우
1. 사용자 변수가 서브 쿼리에 사용된 경우
2. not-deterministic 속성의 스토어드 루틴이 서브 쿼리 내에 사용된 경우
3. UUID()나 RAND()와 같이 결과값이 호출될 때마다 달라지는 함수가 서브 쿼리에 사용된 경우|
|UNCACHEABLE UNION|union 쿼리 결과가 내부적인 캐시 공간에 저장되지 못하는 경우|
|MATERIALIZED|서브 쿼리의 내용을 임시 테이블로 구체화(materialization)하는 경우|
|INSERT|insert문의 실행계획|

{code:sql}
--UNION
MariaDB [employees]> explain
-> select tb.* from (
-> (select emp_no from employees e1 limit 10)
-> union all
-> (select emp_no from employees e2 limit 10)
-> union all
-> (select emp_no from employees e3 limit 10)
-> ) tb;
+------+-------------+------------+-------+---------------+-------------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+------------+-------+---------------+-------------+---------+------+--------+-------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 30 | |
| 2 | DERIVED | e1 | index | NULL | ix_hiredate | 3 | NULL | 299335 | Using index |
| 3 | UNION | e2 | index | NULL | ix_hiredate | 3 | NULL | 299335 | Using index |
| 4 | UNION | e3 | index | NULL | ix_hiredate | 3 | NULL | 299335 | Using index |
+------+-------------+------------+-------+---------------+-------------+---------+------+--------+-------------+
4 rows in set (0.00 sec)

--DEPENDENT UNION & UNION RESULT
MariaDB [employees]> explain
-> select *
-> from employees e1
-> where e1.emp_no in (
-> select e2.emp_no from employees e2 where e2.first_name='Matt'
-> union
-> select e3.emp_no from employees e3 where e3.first_name='Matt'
-> );
+------+--------------------+------------+--------+----------------------+---------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+------------+--------+----------------------+---------+---------+------+--------+-------------+
| 1 | PRIMARY | e1 | ALL | NULL | NULL | NULL | NULL | 299335 | Using where |
| 2 | DEPENDENT SUBQUERY | e2 | eq_ref | PRIMARY,ix_firstname | PRIMARY | 4 | func | 1 | Using where |
| 3 | DEPENDENT UNION | e3 | eq_ref | PRIMARY,ix_firstname | PRIMARY | 4 | func | 1 | Using where |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+------+--------------------+------------+--------+----------------------+---------+---------+------+--------+-------------+
4 rows in set (0.00 sec)

--DEPENDENT SUBQUERY
MariaDB [employees]> explain
-> select e.first_name,
-> (select count(*)
-> from dept_emp de, dept_manager dm
-> where dm.dept_no=de.dept_no and de.emp_no=e.emp_no) as cnt
-> from employees e
-> where e.first_name='Matt';
+------+--------------------+-------+------+---------------------------+-------------------+---------+----------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+-------+------+---------------------------+-------------------+---------+----------------------+------+--------------------------+
| 1 | PRIMARY | e | ref | ix_firstname | ix_firstname | 16 | const | 233 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | de | ref | PRIMARY,ix_empno_fromdate | ix_empno_fromdate | 4 | employees.e.emp_no | 1 | Using index |
| 2 | DEPENDENT SUBQUERY | dm | ref | PRIMARY | PRIMARY | 4 | employees.de.dept_no | 1 | Using index |
+------+--------------------+-------+------+---------------------------+-------------------+---------+----------------------+------+--------------------------+
3 rows in set (0.00 sec)

--DERIVED
MariaDB [employees]> explain
-> select *
-> from (select de.emp_no from dept_emp de group by de.emp_no) tb,
-> employees e
-> where e.emp_no=tb.emp_no;
+------+-------------+------------+--------+---------------+-------------------+---------+-----------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+------------+--------+---------------+-------------------+---------+-----------+--------+-------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 331570 | |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | tb.emp_no | 1 | |
| 2 | DERIVED | de | index | NULL | ix_empno_fromdate | 7 | NULL | 331570 | Using index |
+------+-------------+------------+--------+---------------+-------------------+---------+-----------+--------+-------------+
3 rows in set (0.00 sec)

--UNCACHEABLE SUBQUERY
MariaDB [employees]> explain
-> select *
-> from employees e
-> where e.emp_no = (
-> select @status from dept_emp de where de.dept_no='d005'
-> );
+------+----------------------+-------+-------+---------------+---------+---------+-------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+----------------------+-------+-------+---------------+---------+---------+-------+--------+--------------------------+
| 1 | PRIMARY | e | const | PRIMARY | PRIMARY | 4 | const | 1 | Using where |
| 2 | UNCACHEABLE SUBQUERY | de | ref | PRIMARY | PRIMARY | 4 | const | 165785 | Using where; Using index |
+------+----------------------+-------+-------+---------------+---------+---------+-------+--------+--------------------------+
2 rows in set (0.01 sec)

MariaDB [employees]> explain
-> select *
-> from employees e
-> where e.emp_no in (select emp_no from salaries where salary between 100 and 1000);
+------+--------------+-------------+--------+-------------------+-----------+---------+---------------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+-------------------+-----------+---------+---------------------------+------+--------------------------+
| 1 | PRIMARY | <subquery2> | ALL | distinct_key | NULL | NULL | NULL | 1 | |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.salaries.emp_no | 1 | |
| 2 | MATERIALIZED | salaries | range | PRIMARY,ix_salary | ix_salary | 4 | NULL | 1 | Using where; Using index |
+------+--------------+-------------+--------+-------------------+-----------+---------+---------------------------+------+--------------------------+
3 rows in set (0.00 sec)

--INSERT
MariaDB [employees]> explain
-> insert into employees values (1, '2014-01-01', 'Matt', 'Lee', 'M', '2014-01-02');
+------+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+------+-------+
| 1 | INSERT | employees | ALL | NULL | NULL | NULL | NULL | NULL | NULL |
+------+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

MariaDB [employees]> explain
-> update employees set gender='F' where first_name='Matt';
+------+-------------+-----------+-------+---------------+--------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+---------------+--------------+---------+------+------+-------------+
| 1 | SIMPLE | employees | range | ix_firstname | ix_firstname | 16 | NULL | 233 | Using where |
+------+-------------+-----------+-------+---------------+--------------+---------+------+------+-------------+
1 row in set (0.00 sec)
{code}

** table 컬럼
**# 테이블 이름에 별칭이 있는 경우 실행 계획에서 별칭으로 표시
**# 테이블이 없거나 dual 테이블 사용 시 NULL로 표시
{code:sql}
MariaDB [employees]> explain select now();
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

MariaDB [employees]> explain select now() from dual;
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
{code}

\\

h4. type 컬럼

* 각 테이블의 레코드를 어떤 방식으로 읽었는지를 나타냄

|system|레코드가 1건만 존재하는 테이블 또는 한 건도 존재하는 않는 테이블을 참조하는 형태의 접근 방법, InnoDB, XtraDB 스토리지 엔진에서는 안나오고 MyISAM, MEMORY 테이블에서만 사용|
|const|테이블의 레코드의 건수에 관계없이 쿼리가 프라이머리 키나 유니크 키 컬럼을 이용하는 where 조건절을 가지고 있으며, 반드시 1건을 반환하는 쿼리의 처리 방식|
|eq_ref|조인에서 처음 읽은 테이블의 컬럼 값을 그 다음 읽어야 할 테이블의 프라이머리 키나 유니크 키 컬럼의 검색 조건에 사용할 때|
|ref|조인의 순서와 인덱스의 종류에 관계없이 동등 조건으로 검색|
|fulltext|MariaDB의 전문 검색 인덱스를 사용해 레코드를 읽는 접근 방법을 의미|
|ref_or_null|ref 방식 또는 NULL 비교 접근 방식|
|unique_subquery|where 조건절에서 사용될 수 있는 IN(sebquery)형태의 쿼리를 위한 접근 방식|
|index_subquery|IN(subquery)형태의 조건에서 subquery의 반환 값에 중복된 값이 있을 수 있지만 인덱스를 이용해 중복된 값을 제거|
|range|인덱스 레인지 스캔 형태의 접근 방법|
|index_merge|2개 이상의 인덱스를 이용해 각각의 검색 결과를 만들어낸 후 그 결과를 병합하는 처리 방식|
|index|인덱스 풀 스캔|
|ALL|테이블 풀 스캔|

{code:sql}
-- const
MariaDB [employees]> explain select * from employees where emp_no=10001;
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | employees | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

--eq_ref
MariaDB [employees]> explain
-> select * from dept_emp de, employees e
-> where e.emp_no=de.emp_no and de.dept_no='d005';
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+--------+-------------+
| 1 | SIMPLE | de | ref | PRIMARY,ix_empno_fromdate | PRIMARY | 4 | const | 165785 | Using where |
| 1 | SIMPLE | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.emp_no | 1 | |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+--------+-------------+
2 rows in set (0.00 sec)

--ref
MariaDB [employees]> explain
-> select * from dept_emp where dept_no='d005';
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
| 1 | SIMPLE | dept_emp | ref | PRIMARY | PRIMARY | 4 | const | 165785 | Using where |
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
1 row in set (0.00 sec)

--fulltext
MariaDB [employees]> explain
-> select *
-> from employee_name
-> where match(first_name, last_name) against ('Facello' in boolean mode);
+------+-------------+---------------+----------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------------+----------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | employee_name | fulltext | fx_name | fx_name | 0 | | 1 | Using where |
+------+-------------+---------------+----------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

--ref_or_null
MariaDB [employees]> explain
-> select *
-> from titles where to_date='1985-03-01' or to_date is null;
+------+-------------+--------+-------------+---------------+-----------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+--------+-------------+---------------+-----------+---------+-------+------+--------------------------+
| 1 | SIMPLE | titles | ref_or_null | ix_todate | ix_todate | 4 | const | 2 | Using where; Using index |
+------+-------------+--------+-------------+---------------+-----------+---------+-------+------+--------------------------+
1 row in set (0.01 sec)

--range
MariaDB [employees]> explain
-> select * from employees where emp_no between 10002 and 10004;
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | employees | range | PRIMARY | PRIMARY | 4 | NULL | 3 | Using where |
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

--index_merge
MariaDB [employees]> explain
-> select *
-> from employees
-> where emp_no between 10001 and 11000
-> or first_name='Smith';
+------+-------------+-----------+-------------+----------------------+----------------------+---------+------+------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------------+----------------------+----------------------+---------+------+------+------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | PRIMARY,ix_firstname | PRIMARY,ix_firstname | 4,16 | NULL | 1000 | Using union(PRIMARY,ix_firstname); Using where |
+------+-------------+-----------+-------------+----------------------+----------------------+---------+------+------+------------------------------------------------+
1 row in set (0.00 sec)

--index
MariaDB [employees]> explain
-> select *
-> from departments
-> order by dept_name desc limit 10;
+------+-------------+-------------+-------+---------------+-------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------+-------+---------------+-------------+---------+------+------+-------------+
| 1 | SIMPLE | departments | index | NULL | ux_deptname | 42 | NULL | 9 | Using index |
+------+-------------+-------------+-------+---------------+-------------+---------+------+------+-------------+
1 row in set (0.00 sec)
{code}

\\

h4. possibel_keys 컬럼

* 옵티마이저가 최적의 실행 계획을 만들기 위해 후보로 선정했던 접근 방식에서 사용되는 인덱스 목록
* "사용될 법했던 인덱스의 목록"으로 실제 그 인덱스를 사용하지는 않을 수 있음

\\

h4. key 컬럼

* 최종 선택된 실행 계획에서 사용하는 인덱스를 의미
* PRIMARY인 경우에는 프라이머리 키를 사용한다는 의미, 그 의외의 값은 테이블이나 인덱스를 생성할 때 부여했던 고유 이름

\\

h4. key_len 컬럼

* 쿼리를 처리하기 위해 다중 컬럼으로 구성된 인덱스에서 몇 개의 컬럼까지 사용했는지 표시
* 인덱스의 각 레코드에서 몇 바이트까지 사용했는지 알려주는 값

{code:sql}
MariaDB [employees]> explain
-> select * from dept_emp where dept_no='d005';
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
| 1 | SIMPLE | dept_emp | ref | PRIMARY | PRIMARY | 4 | const | 165785 | Using where |
+------+-------------+----------+------+---------------+---------+---------+-------+--------+-------------+
1 row in set (0.00 sec)

MariaDB [employees]> explain
-> select * from dept_emp where dept_no='d005' and emp_no=10001;
+------+-------------+----------+-------+---------------------------+---------+---------+-------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------------------+---------+---------+-------------+------+-------+
| 1 | SIMPLE | dept_emp | const | PRIMARY,ix_empno_fromdate | PRIMARY | 8 | const,const | 1 | |
+------+-------------+----------+-------+---------------------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)

MariaDB [employees]> explain
-> select * from titles where to_date <= '1985-10-10';
+------+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
| 1 | SIMPLE | titles | range | ix_todate | ix_todate | 4 | NULL | 51 | Using where; Using index |
+------+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
-- to_date is nullable: date 3byte + null 1byte
{code}

\\

h4. ref 컬럼

* 참조 조건(equal 비교 조건)으로 어떤 값이 제공됐는지 표시
* 상수 값을 지정했다면 const로 표시, 다른 테이블의 컬럼이면 그 테이블 명과 컬럼 명이 표시

{code:sql}
MariaDB [employees]> explain
-> select * from employees e, dept_emp de
-> where e.emp_no=de.emp_no;
+------+-------------+-------+--------+-------------------+---------+---------+---------------------+--------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+-------------------+---------+---------+---------------------+--------+-------+
| 1 | SIMPLE | de | ALL | ix_empno_fromdate | NULL | NULL | NULL | 331570 | |
| 1 | SIMPLE | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.emp_no | 1 | |
+------+-------------+-------+--------+-------------------+---------+---------+---------------------+--------+-------+
2 rows in set (0.00 sec)

MariaDB [employees]> explain
-> select * from employees e, dept_emp de
-> where e.emp_no=(de.emp_no-1);
+------+-------------+-------+--------+---------------+---------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+---------+---------+------+--------+-------------+
| 1 | SIMPLE | de | ALL | NULL | NULL | NULL | NULL | 331570 | |
| 1 | SIMPLE | e | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | Using where |
+------+-------------+-------+--------+---------------+---------+---------+------+--------+-------------+
2 rows in set (0.00 sec)
{code}

\\

h4. rows 컬럼

* 실행 계획의 효율성 판단을 위해 예측했던 레코드 건수를 표시

\\

h4. extra 컬럼

|constrow not found|쿼리의 실행계획에서 const 접근 방식으로 테이블을 읽었지만 실제로 해당 테이블에 레코드가 1건도 존재하지 않는 경우|
|Distinct|중복 제거 표시|
|Full scan on NUll key|col1 IN (select col2 from ...) 쿼리에서 col1이 값이 NULL이면 풀 테이블 스캔을 사용할 것을 표시|
|Impossible HAVING|쿼리에 사용된 having절의 조건을 만족하는 레코드가 없을 때 표시, 쿼리가 제대로 작성되지 못한 경우가 대부분으로 쿼리를 다시 점검|
|Impossible WHERE|where 조건이 항상 false가 될 수밖에 없는 경우|
|Impossible WHERE noticed after reading const tables|실행 계획을 만드는 과정에서 쿼리의 일부분을 실행해 본 후 where 조건이 false인 경우|
|No matching min/max row|min(), max()와 같은 집합 함수가 있는 쿼리의 조건절에 일치하는 레코드가 한 건도 없을 때 표시|
|No matching row in const table|조인에 사용된 테이블에서 const방식으로 접근할 때 일치하는 레코드가 없는 것을 표시|
|No tables used|from절이 없는 쿼리 문장이나 "from dual"을 표시|
|Not exists|outer조인을 이용해 안티-조인을 수행하는 쿼리 표시|
|Range checked for each record(index map: N)|조인 조건이 모두 변수인 경우 매 레코드마다 인덱스 레인지 스캔을 표시|

{code:sql}
--Distinct
MariaDB [employees]> explain
-> select distinct d.dept_no
-> from departments d, dept_emp de where de.dept_no=d.dept_no;
+------+-------------+-------+-------+---------------+---------+---------+---------------------+-------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+---------------------+-------+------------------------------+
| 1 | SIMPLE | d | index | PRIMARY | PRIMARY | 4 | NULL | 9 | Using index; Using temporary |
| 1 | SIMPLE | de | ref | PRIMARY | PRIMARY | 4 | employees.d.dept_no | 20723 | Using index; Distinct |
+------+-------------+-------+-------+---------------+---------+---------+---------------------+-------+------------------------------+
2 rows in set (0.00 sec)

--Full scan on NULL key
MariaDB [employees]> explain
-> select d.dept_no, null in (select id.dept_name from departments id)
-> from departments d;
+------+-------------+-------+----------------+---------------+-------------+---------+-------+------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+----------------+---------------+-------------+---------+-------+------+-------------------------------------------------+
| 1 | PRIMARY | d | index | NULL | PRIMARY | 4 | NULL | 9 | Using index |
| 2 | SUBQUERY | id | index_subquery | ux_deptname | ux_deptname | 42 | const | 1 | Using index; Using where; Full scan on NULL key |
+------+-------------+-------+----------------+---------------+-------------+---------+-------+------+-------------------------------------------------+
2 rows in set (0.00 sec)

--Impossible HAVING
MariaDB [employees]> explain
-> select e.emp_no, count(*) as cnt
-> from employees e
-> where e.emp_no=10001
-> group by e.emp_no
-> having e.emp_no is null;
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible HAVING |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------+
1 row in set (0.00 sec)

--Impossible WHERE
MariaDB [employees]> explain
-> select * from employees where emp_no is null;
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------+
1 row in set (0.00 sec)

--Impossible WHERE noticed after reading const tables
MariaDB [employees]> explain
-> select * from employees where emp_no=0;
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+------+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.00 sec)

--No matching min/max row
MariaDB [employees]> explain
-> select min(dept_no), max(dept_no)
-> from dept_emp where dept_no='';
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No matching min/max row |
+------+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
1 row in set (0.00 sec)

--No tables used
MariaDB [employees]> explain select now();
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

MariaDB [employees]> explain select now() from dual;
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

--Not exists
MariaDB [employees]> explain
-> select *
-> from dept_emp de
-> left join departments d on de.dept_no=d.dept_no
-> where d.dept_no is null;
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+-------------------------+
| 1 | SIMPLE | de | ALL | NULL | NULL | NULL | NULL | 331570 | |
| 1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.dept_no | 1 | Using where; Not exists |
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+-------------------------+
2 rows in set (0.00 sec)

--Range checked for each record
MariaDB [employees]> explain select * from employees e1, employees e2 where e2.emp_no >= e1.emp_no;
+------+-------------+-------+------+---------------+------+---------+------+--------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+--------+------------------------------------------------+
| 1 | SIMPLE | e1 | ALL | PRIMARY | NULL | NULL | NULL | 299335 | |
| 1 | SIMPLE | e2 | ALL | PRIMARY | NULL | NULL | NULL | 299335 | Range checked for each record (index map: 0x1) |
+------+-------------+-------+------+---------------+------+---------+------+--------+------------------------------------------------+
2 rows in set (0.00 sec)
{code}