정의와 간단한 설명
EXPLAIN SELECT * FROM users WHERE age > 30;
| const / eq_ref | 매우 빠른 방식 (기본키나 고정된 값) |
| ref | 인덱스를 사용한 단일 행 접근 |
| range | 범위 검색 (ex. BETWEEN, >, < 등) |
| index | 인덱스 full scan |
| ALL | 테이블 full scan (가장 느림) ← 주의 |
| id | 실행 순서 ID. 서브쿼리나 조인 순서를 구분 |
| select_type | 쿼리 유형. (SIMPLE, PRIMARY, SUBQUERY 등) |
| table | 접근 대상 테이블 이름 |
| partitions | 사용할 파티션 (있을 경우) |
| type | 조인 방식. 성능을 좌우하는 중요한 항목 |
| possible_keys | 사용 가능한 인덱스 목록 |
| key | 실제 사용된 인덱스 |
| key_len | 사용된 인덱스의 길이 (바이트 단위) |
| ref | 인덱스와 비교되는 컬럼 또는 상수 |
| rows | DB가 예상하는 읽게 될 행 수 |
| filtered | 조건에 의해 필터링될 확률 (%) |
| Extra | 추가적인 정보 (Using index, Using where 등) |
학생테이블, 강의(course)테이블이 있다고 가정했을때
쿼리익스플랜를 확인하기위해 explain 키워드를 SQL명령어 상단에 붙인다.
explain
select
students.student_name,
courses.subject_name
from
STUDENT_COURSES student_courses
inner join STUDENTS students on students.student_id = student_courses.student_id
inner join COURSES courses on courses.subject_code = student_courses.subject_code
+--+-----------+---------------+----------+------+--------------------+-------+-------+----------------------------------------+----+--------+-----------+
|id|select_type|table |partitions|type |possible_keys |key |key_len|ref |rows|filtered|Extra |
+--+-----------+---------------+----------+------+--------------------+-------+-------+----------------------------------------+----+--------+-----------+
|1 |SIMPLE |student_courses|null |ALL |FK_Student,FK_Course|null |null |null |4385|100 |Using where|
|1 |SIMPLE |students |null |eq_ref|PRIMARY |PRIMARY|8 |playgrounds.student_courses.student_id |1 |100 |null |
|1 |SIMPLE |courses |null |eq_ref|PRIMARY |PRIMARY|202 |playgrounds.student_courses.subject_code|1 |100 |null |
+--+-----------+---------------+----------+------+--------------------+-------+-------+----------------------------------------+----+--------+-----------+
확인해야할 정보
id 항목은 연결된 SELECT 문의 각 단계를 식별합니다. 만약 id가 같다면, 이는 해당 단계가 동일한 SELECT 문인것.id 값의 차이는 두 SELECT 문이 별개의 단계로 처리되는 것을 의미합니다.UNION이 없는 기본 SELECT문을 나타냅니다. 여기선 복잡한 구조를 다루지 않고 단일 테이블에 대한 간결한 조회를 실행합니다.SELECT문이나, 관계형 서브쿼리 또는 UNION을 가진 쿼리를 나타냅니다.SELECT 쿼리 결과를 통합할 때 UNION 명령어를 사용하게 됩니다. 이때 첫 번째 SELECT 이후의 모든 SELECT 절에 대해 이 타입이 표시됩니다.UNION 작업이 마무리되면, 그 결과는 UNION RESULT로 나타나게 됩니다. 이것은 UNION 연산의 최종 결과를 제공합니다.SUBQUERY라 합니다. 그러나 이 유형은 서브쿼리가 FROM 절 이외의 위치에 사용될 때만 적용됩니다.FROM 절에서 서브쿼리가 사용될 때, 그 서브쿼리에 대한 결과는 일종의 일시적인 테이블을 만드는 것으로 간주됩니다. MySQL에서는 이렇게 FROM 절에서 사용된 서브쿼리를 파생 테이블이라고 하며, 일반적인 RDBMS는 인라인 뷰(Inline View) 또는 서브 셀렉트(Sub Select)라고 부릅니다.
table 필드는 쿼리가 참조하는 테이블의 이름을 의미한다.EXPLAIN 결과에 각각의 테이블에 대한 레코드가 표시됩니다.table 필드가 언제나 물리적 테이블을 나타내는 것은 아니라는 점입니다.explain
select
users.id,
orders.order_number,
products.product_name
from
USERS users
inner join ORDERS orders on orders.user_id = users.id
inner join PRODUCTS products on products.id = orders.product_id
where
users.country = 'USA';
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+
| 1 | SIMPLE | users | ALL | PRIMARY | NULL | NULL | NULL | 1000 | Using where |
| 1 | SIMPLE | orders | ref | user_id | user_id | 5 | database.users.id | 10 | |
| 1 | SIMPLE | products | eq_ref| PRIMARY | PRIMARY | 4 | database.orders.product_id | 1 | |
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+ 파티셔닝된 테이블에 대한 쿼리를 수행할 때 참조되는 파티션이 무엇인지를 나타내는 속성
만약 쿼리가 테이블의 모든 파티션을 스캔한다면, partitions 필드는 NULL 값이 된다.
쿼리가 파티션을 올바르게 이용해 한 개 혹은 일부 파티션만 스캔한다면, 이 필드는 해당 파티션 이름을 표시합니다.
explain
select
users.id,
orders.order_number,
products.product_name
from
USERS users
inner join ORDERS orders on orders.user_id = users.id
inner join PRODUCTS products on products.id = orders.product_id
where
users.country = 'USA';
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | partiitions | Extra |
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+-------------+
| 1 | SIMPLE | users | ALL | PRIMARY | NULL | NULL | NULL | 1000 | p0,p1 | Using where |
| 1 | SIMPLE | orders | ref | user_id | user_id | 5 | database.users.id | 10 | p0 | |
| 1 | SIMPLE | products | eq_ref| PRIMARY | PRIMARY | 4 | database.orders.product_id | 1 | NULL | |
+-----+-------------+----------+-------+---------------+----------+---------+----------------------------+------+-------------+-------------+
MySQL서버가 각 테이블의 레코드를 어떤 방식으로 읽었는지를 나타내는 속성이다.
아래 표를 참고하자.
| const / eq_ref | 매우 빠른 방식 (기본키나 고정된 값) |
| ref | 인덱스를 사용한 단일 행 접근 |
| range | 범위 검색 (ex. BETWEEN, >, < 등) |
| index | 인덱스 full scan |
| ALL | 테이블 full scan (가장 느림) ← 주의 |
딥하게 공부