집 >데이터 베이스 >MySQL 튜토리얼 >MySQL의 EXPLAIN 해석 명령 소개(예제 포함)
이 기사에서는 MySQL의 EXPLAIN 해석 명령에 대해 소개합니다(예제 포함). 도움이 필요한 친구가 참고할 수 있기를 바랍니다.
1 EXPLAIN 개념
EXPLAIN은 MySQL이 sql을 실행하는 방법에 대한 몇 가지 정보를 제공합니다.
2 EXPLAIN 출력 열 정보
EXPLAIN 출력 필드 정보
첫 번째 열: 열 이름, 두 번째 열: FORMAT = JSON일 때 출력에 표시되는 해당 속성 이름, 세 번째 열: 필드 의미
열 | JSON 이름 | 의미 |
---|---|---|
id | select_id | 식별번호 선택 |
select_type | None | 유형 선택 |
table | table_name | 이 데이터 행은 어떤 테이블의 |
일치하는 파티션과 관련하여 분할되지 않은 테이블의 경우 값은 비어 있습니다 | type | |
사용된 연결 범주, 인덱스 사용 여부 | available_keys | |
MySQL이 이 테이블에서 행을 찾는 데 사용할 수 있는 인덱스는 무엇입니까? | key | |
MySQL은 실제로 사용할 키(인덱스)를 결정합니다 | key_len | |
My SQL은 다음과 같이 결정했습니다. 본드 길이를 사용하십시오. 키가 NULL이면 길이는 NULL | ref | |
인덱스에 연결된 열 | rows | |
mysql이 sql 실행 시 확인해야 한다고 생각하는 행 수 | filtered | |
는 이 쿼리 조건 | Extra | |
추가 정보 | 2.1 id |
2.2 select_type
SELECT 유형, 모든 유형은 아래 표에 표시됩니다. JSON 형식의 EXPLAIN은 SIMPLE 또는 PRIMARY가 아닌 한 SELECT 유형을 query_block의 속성으로 노출합니다. JSON 이름(해당되는 경우 없음)도 표에 표시됩니다.
select_type 값의미 | ||
---|---|---|
간단한 SELECT(UNION 또는 하위 쿼리 등을 사용하지 않음) | PRIMARY | |
중첩됨 쿼리 가장 바깥쪽 쿼리인 경우 | UNION | |
UNION의 두 번째 또는 후속 SELECT 문 | DEPENDENT UNION | |
UNION SELECT 문의 두 번째 또는 후속 SELECT 문은 다음에 따라 달라집니다. 외부 쿼리의 결과 | UNION RESULT | |
UNION | SUBQUERY | |
하위 쿼리의 첫 번째 선택 | DEPENDENT S UBQUERY | |
먼저 하위 쿼리의 선택, 외부 쿼리에 따라 다름 | DERIVED | |
파생 테이블(하위 쿼리에서 생성된 임시 테이블) | MATERIALIZED | |
구체화된 하위 쿼리 | UNCACHEABLE SUBQUERY | |
결과를 캐시할 수 없는 하위 쿼리는 외부 쿼리의 각 행에 대해 다시 계산해야 합니다. | UNCACHEABLE UNION | |
UNION은 캐시할 수 없습니다. 하위 쿼리의 두 번째 또는 후속 선택(UNCACHEABLE SUBQUERY 참조) ) |
테이블 정보(나중에 시연용): mysql> show create table t_a; ------+ | t_a | CREATE TABLE `t_a` ( `id` bigint(20) NOT NULL DEFAULT '0', `age` int(20) DEFAULT NULL, `code` int(20) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_code` (`code`), KEY `age_key` (`age`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk | +-------+----------------------------------- ------+ 1 row in set (0.03 sec) SIMPLE: 단순 SELECT(UNION이나 하위 쿼리 등을 사용하지 않음) mysql> explain select * from t_a where id =1; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.03 sec) PRIMARY: 쿼리 중첩 시 가장 바깥쪽 쿼리 mysql> explain select * from t_a where num >(select num from t_a where id = 3); +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | 1 | PRIMARY | t_a | NULL | range | num_key | num_key | 5 | NULL | 6 | 100.00 | Using where; Using index | | 2 | SUBQUERY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ 2 rows in set, 1 warning (0.03 sec) UNION: UNION의 두 번째 또는 그 이후 SELECT 문 mysql> explain select * from t_a where id =9 union all select * from t_a; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | PRIMARY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | | 2 | UNION | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using index | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ 2 rows in set, 1 warning (0.04 sec) DEPENDENT UNION: 외부 쿼리에 따라 UNION의 두 번째 또는 후속 SELECT 문 mysql> explain select * from t_a where id in (select id from t_a where id >8 union all select id from t_a where id =5); +----+--------------------+-------+------------+--------+---------------+---------+---------+-------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+-------+------------+--------+---------------+---------+---------+-------+------+----------+--------------------------+ | 1 | PRIMARY | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using where; Using index | | 2 | DEPENDENT SUBQUERY | t_a | NULL | eq_ref | PRIMARY | PRIMARY | 8 | func | 1 | 100.00 | Using where; Using index | | 3 | DEPENDENT UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index | +----+--------------------+-------+------------+--------+---------------+---------+---------+-------+------+----------+--------------------------+ 3 rows in set, 1 warning (0.08 sec) UNION RESULT: UNION mysql> explain select num from t_a where id = 3 union select num from t_a where id =4; +----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+ | 1 | PRIMARY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | | 2 | UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+ 3 rows in set, 1 warning (0.03 sec) SUBQUERY: 하위 쿼리 A의 두 번째 또는 후속 SELECT 문 SELECT mysql> explain select * from t_a where num >(select num from t_a where id = 3); +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | 1 | PRIMARY | t_a | NULL | range | num_key | num_key | 5 | NULL | 6 | 100.00 | Using where; Using index | | 2 | SUBQUERY | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ 2 rows in set, 1 warning (0.03 sec) DEPENDENT SUBQUERY: 외부 쿼리에 의존하는 하위 쿼리의 첫 번째 선택 mysql> explain select * from t_a where num in(select num from t_a where id = 3 union select num from t_a where id =4); +----+--------------------+------------+------------+-------+-----------------+---------+---------+-------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+------------+------------+-------+-----------------+---------+---------+-------+------+----------+--------------------------+ | 1 | PRIMARY | t_a | NULL | index | NULL | num_key | 5 | NULL | 9 | 100.00 | Using where; Using index | | 2 | DEPENDENT SUBQUERY | t_a | NULL | const | PRIMARY,num_key | PRIMARY | 8 | const | 1 | 100.00 | NULL | | 3 | DEPENDENT UNION | t_a | NULL | const | PRIMARY,num_key | PRIMARY | 8 | const | 1 | 100.00 | NULL | | NULL | UNION RESULT | <union2,3> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------------+------------+------------+-------+-----------------+---------+---------+-------+------+----------+--------------------------+ 4 rows in set, 1 warning (0.12 sec) DERIVED: 파생 테이블(하위 쿼리에서 생성된 임시 테이블) mysql> explain select a.id from (select id from t_a where id >8 union all select id from t_a where id =5) a; +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ | 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL | | 2 | DERIVED | t_a | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 1 | 100.00 | Using where; Using index | | 3 | UNION | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index | +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+ 3 rows in set, 1 warning (0.12 sec) 2.3 테이블보기 데이터 행 참조? 때로는 실제 테이블 이름일 수도 있고 때로는 다음과 같은 결과일 수도 있습니다
2.4 partitions쿼리된 레코드가 속한 파티션입니다. 분할되지 않은 테이블의 경우 이 값은 NULL입니다. 2.5 유형연결에 사용되는 카테고리와 인덱스 사용 여부. 일반적으로 사용되는 유형은 system, const, eq_ref, ref, range, index, ALL(왼쪽에서 오른쪽으로 갈수록 성능이 나빠짐) ), 세부 정보 EXPLAIN 조인 유형 보기 NULL: MySQL은 최적화 프로세스 중에 명령문을 분해하고 실행 중에 테이블이나 인덱스에 액세스할 필요도 없습니다. 예를 들어 인덱스 열에서 최소값을 선택하는 것은 다음을 통해 완료될 수 있습니다. 별도의 인덱스 조회 system: 데이터 행이 하나만 있는 이 테이블(쿼리되는 임시 테이블일 수도 있음)(= 시스템 테이블) const const: 테이블에 있는 특수한 경우입니다. 일치하는 행은 대부분 쿼리 시작 부분에서 읽혀집니다. 행이 하나뿐이므로 이 행의 열 값은 나머지 최적화 프로그램에서 상수로 처리될 수 있습니다. const 테이블은 한 번만 읽기 때문에 빠릅니다! const는 조건이 PRIMARY KEY 또는 UNIQUE 인덱스이고 상수 값과 비교되는 경우 쿼리의 모든 부분에 사용됩니다. SELECT * from tbl_name WHERE primary_key=1; SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2; --例子 mysql> explain select * from t_a where id =1; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | t_a | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.07 sec) eq_ref: 이전 테이블의 각 행 조합에 대해 이 테이블에서 한 행을 읽습니다. system 및 const 외에도 이것이 최고의 연결 유형입니다. 조인이 인덱스의 모든 부분을 사용하고 인덱스가 기본 키이거나 null이 아닌 고유 인덱스인 경우에 사용됩니다. eq_ref는 = 연산자를 사용하여 비교된 인덱스 열에 사용할 수 있습니다. 비교 값은 상수이거나 이 테이블 이전에 읽은 테이블의 열을 사용하는 표현식일 수 있습니다. SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1; --例子(t_b为t_a的复制表,表结构相同) mysql> explain select * from t_a,t_b where t_a.code=t_b.code; +----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------+ | 1 | SIMPLE | t_a | NULL | ALL | uk_code | NULL | NULL | NULL | 9 | 100.00 | NULL | | 1 | SIMPLE | t_b | NULL | eq_ref | uk_code | uk_code | 4 | test.t_a.code | 1 | 100.00 | NULL | +----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------+ 2 rows in set, 1 warning (0.03 sec) ref 이전 테이블의 각 행 조합에 대해 일치하는 인덱스 값이 있는 모든 행을 이 테이블에서 읽습니다. 조인이 키의 가장 왼쪽 접두사만 사용하거나 키가 UNIQUE 또는 PRIMARY KEY가 아닌 경우(즉, 조인으로 인해 키워드 쿼리를 기반으로 단일 행이 생성될 수 없는 경우) ref를 사용하세요. 이 조인 유형은 소수의 행에만 일치하는 키를 사용하는 경우에 적합합니다. ref는 = 또는 <=> 연산자를 사용하여 인덱싱된 열에 사용될 수 있습니다. SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1; --例子(t_b为t_a的复制表,表结构相同) mysql> explain select * from t_a,t_b where t_a.age=t_b.age; +----+-------------+-------+------------+------+---------------+---------+---------+--------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+---------+---------+--------------+------+----------+-------------+ | 1 | SIMPLE | t_a | NULL | ALL | age_key | NULL | NULL | NULL | 9 | 100.00 | Using where | | 1 | SIMPLE | t_b | NULL | ref | age_key | age_key | 5 | test.t_a.age | 1 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+---------+---------+--------------+------+----------+-------------+ 2 rows in set, 1 warning (0.03 sec) fulltext: FULLTEXT 인덱스를 사용하여 조인을 수행합니다. ref_or_null: 이 조인 유형은 ref와 유사하지만 MySQL이 구체적으로 검색할 수 있다는 점이 추가되었습니다. NULL 값을 포함하는 행의 경우. 이러한 조인 유형의 최적화는 하위 쿼리를 해결하는 데 자주 사용됩니다. SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL; --例子 mysql> explain select * from t_a where t_a.age =3 or t_a.age is null; +----+-------------+-------+------------+-------------+---------------+---------+---------+-------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------------+---------------+---------+---------+-------+------+----------+-----------------------+ | 1 | SIMPLE | t_a | NULL | ref_or_null | age_key | age_key | 5 | const | 2 | 100.00 | Using index condition | +----+-------------+-------+------------+-------------+---------------+---------+---------+-------+------+----------+-----------------------+ 1 row in set, 1 warning (0.03 sec) index_merge: 이 조인 유형은 인덱스 병합 최적화 방법이 사용됨을 나타냅니다. 이 경우 키 열에는 사용된 인덱스 목록이 포함되고, key_len에는 사용된 인덱스의 가장 긴 키 요소가 포함됩니다. SELECT * FROM ref_table WHERE idx1=expr1 OR idx2 =expr2; --例子 mysql> explain select * from t_a where t_a.code =3 or t_a.age = 3; +----+-------------+-------+------------+-------------+-----------------+-----------------+---------+------+------+----------+-------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------------+-----------------+-----------------+---------+------+------+----------+-------------------------------------------+ | 1 | SIMPLE | t_a | NULL | index_merge | uk_code,age_key | uk_code,age_key | 4,5 | NULL | 2 | 100.00 | Using union(uk_code,age_key); Using where | +----+-------------+-------+------------+-------------+-----------------+-----------------+---------+------+------+----------+-------------------------------------------+ 1 row in set, 1 warning (0.03 sec) unique_subquery: 이 유형은 다음 형식의 IN 하위 쿼리의 참조를 대체합니다. value IN (SELECT Primary_key FROM Single_table WHERE some_expr) value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。 index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr) Unique_subquery는 하위 쿼리가 더 효율적입니다. index_subquery: 이 조인 유형은 Unique_subquery와 유사합니다. IN 하위 쿼리는 대체될 수 있지만 다음 형식의 하위 쿼리에 있는 고유하지 않은 인덱스에만 해당됩니다.
mysql> explain select * from t_a where id > 8; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t_a | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 1 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.03 sec)와 비교할 때 range🎜를 사용할 수 있습니다. index: 이 조인 유형은 인덱스 트리만 검색한다는 점을 제외하면 ALL과 동일합니다. 인덱스 파일은 일반적으로 데이터 파일보다 작기 때문에 일반적으로 ALL보다 빠릅니다. MySQL은 쿼리가 단일 인덱스의 일부인 열만 사용할 때 이 조인 유형을 사용할 수 있습니다. 🎜🎜 ALL: 이전 테이블의 모든 행 조합에 대해 전체 테이블 스캔을 수행합니다. 테이블이 const로 표시되지 않은 첫 번째 테이블인 경우 일반적으로 좋지 않으며, 이 경우 일반적으로 나쁩니다. 일반적으로 이전 테이블의 상수 값이나 열 값을 기반으로 행을 검색할 수 있도록 ALL을 사용하지 않고도 인덱스를 더 추가하는 것이 가능합니다. 2.6 available_keyspossible_keys 열은 MySQL이 이 테이블에서 행을 찾는 데 사용할 수 있는 인덱스를 나타냅니다. 이 열은 EXPLAIN 출력에 표시된 테이블 순서와 완전히 독립적입니다. 이는 available_keys의 일부 키가 생성된 테이블 순서에 실제로 사용될 수 없음을 의미합니다. 열이 NULL이면 연관된 인덱스가 없습니다. 이 경우 WHERE 절을 확인하여 인덱싱에 적합한 특정 열을 참조하는지 확인하여 쿼리 성능을 향상시킬 수 있습니다. 그렇다면 적절한 인덱스를 생성하고 EXPLAIN 2.7 key로 쿼리를 다시 확인해보세요. 키 열에는 MySQL이 실제로 사용하기로 결정한 키(인덱스)가 표시됩니다. 인덱스를 선택하지 않으면 키는 NULL입니다. MySQL이 available_keys 열의 인덱스를 사용하거나 무시하도록 하려면 쿼리에서 FORCE INDEX, USE INDEX 또는 IGNORE INDEX를 사용하십시오. 2.8 key_len key_len 열은 MySQL이 사용하기로 결정한 키 길이를 보여줍니다. 키가 NULL이면 길이도 NULL입니다. 2.9 ref참조 열은 테이블에서 행을 선택하는 키와 함께 사용되는 열 또는 상수를 보여줍니다. 2.10 행행 열은 MySQL이 쿼리를 실행할 때 확인해야 한다고 생각하는 행 수를 표시합니다. 2.11 Extra이 열에는 MySQL이 쿼리를 어떻게 해결했는지에 대한 세부 정보가 포함되어 있습니다.
|
위 내용은 MySQL의 EXPLAIN 해석 명령 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!