>  기사  >  데이터 베이스  >  이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

青灯夜游
青灯夜游앞으로
2022-10-21 20:45:031524검색

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

일반적으로 느린 쿼리 SQL语句时会使用EXPLAIN命令来查看SQL语句的执行计划,通过返回的信息,可以了解到Mysql优化器是如何执行SQL 문을 쿼리하고 분석하면 최적화 아이디어를 제공하는 데 도움이 됩니다.

1. explain 함수

explain 명령은 주로 SQL 문의 실행 계획을 보는 데 사용됩니다. 이 명령은 옵티마이저의 SQL 쿼리 문 실행을 시뮬레이션할 수 있으며 SQL을 작성하고 최적화하는 데 도움이 될 수 있습니다. 그렇다면 SQL을 최적화하는 데 도움이 되는 구체적인 정보는 무엇입니까?

  • 테이블 읽기 순서

  • 데이터 읽기 작업의 동작 종류

  • 어떤 인덱스를 사용할 수 있는지

  • 어떤 인덱스가 실제로 사용되는지

  • 테이블 간 참조

  • 행 수 각 테이블은 옵티마이저에 의해 쿼리됩니다

2. 사용 방법 설명

사용법: explain + sql to be running

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

explain은 실행할 SQL에 대한 실행 계획 목록을 반환합니다. , 목록에는 12개의 필드가 포함되어 있으며 각 필드는 실행 계획에서 SQL이 실행되는 방식을 공동으로 설명합니다. 다음 목록에서는 실행 계획 테이블의 필드 의미를 자세히 설명합니다.

key_lenrefrowsfilteredExtra
Field name Description
id 읽기 순서를 결정하는 select 문 쿼리의 시퀀스 번호 of the table
select_type 쿼리의 종류, 즉 데이터 읽기 연산의 연산 종류
table 쿼리의 테이블 이름
partitions Table partitions
type 액세스 유형
possible_keys 사용 가능한 인덱스. 쿼리에 포함된 필드에 인덱스가 있는 경우 해당 인덱스가 나열되지만 실제로 쿼리에서 사용되지 않을 수도 있습니다. 이 필드가 null이지만 필드 키가 null이 아닌 경우 이 상황은 검색 시 사용할 수 있는 보조 인덱스 트리가 없지만 보조 인덱스에 쿼리해야 하는 필드가 포함되어 있으므로 클러스터형 인덱스(클러스터형 인덱스) )는 더 이상 검색되지 않고, 대신 보조 인덱스 트리가 스캔되며(보조 인덱스 트리는 상대적으로 작음) 이때 일반 액세스 유형은 인덱스이며 전체 인덱스 트리가 스캔됩니다. .
key 실제 스캔에 사용되는 인덱스입니다. null인 경우 인덱스는 사용되지 않습니다. 쿼리에 포함 인덱스가 사용되는 경우 인덱스는 키 목록에만 나타납니다.
인덱스에 사용되는 바이트 수입니다. 이 열은 쿼리에 사용된 인덱스의 길이를 계산하는 데 사용할 수 있습니다. 길이가 짧을수록 key_len에 표시되는 값은 사용된 실제 길이가 아닌 인덱스 필드의 최대 길이입니다. 즉, key_len은 테이블을 기반으로 합니다. 정의는 테이블에서 검색되지 않고 계산됩니다.
는 사용되는 인덱스 열을 보여줍니다. 가능하다면 인덱스 열에서 값을 찾는 데 사용되는 열 또는 상수입니다.
테이블 통계 및 인덱스 선택을 기반으로 필요한 레코드를 찾는 데 필요한 읽기를 대략적으로 추정합니다. 행 수;
검색 조건으로 필터링한 후 남은 데이터의 비율입니다.
다른 열에 표시하기에는 적합하지 않지만 매우 중요한 추가 정보가 포함되어 있습니다.
3. 주요 필드 분석

(1) id

select 문 실행 순서 쿼리 번호에는 쿼리에서 선택 절 또는 작업 테이블이 실행되는 순서를 나타내는 숫자 집합이 포함됩니다.

유형 이름ID가 동일합니다. id가 다릅니다id는 같지만 다르며 동시에 존재합니다

(2) select_type

은 데이터 읽기 작업의 작업 유형입니다.

Description
실행 순서 위에서 아래로 다음
subquery인 경우 id의 일련번호가 증가하며, id 값이 클수록 우선 순위가 높아져 더 일찍 실행됩니다.
id가 같으면 그룹으로 간주하여 위에서 아래로 순차적으로 실행됩니다. id 값이 높을수록 우선순위가 높을수록 빨리 실행됩니다
primary쿼리에 복잡한 하위 쿼리가 포함된 경우 가장 바깥쪽 쿼리가 표시됩니다. subquery는 선택 또는 위치 목록에 하위 쿼리를 포함합니다. derivedunion resultmeterializeddependent Union에 표시되는 쿼리 테이블 이름은 여기에 표시된 것은 별칭입니다. 데이터 테이블에 작업이 없으면 null로 표시되거나 다음 중 하나가 될 수 있습니다. DescriptionN>M,N>
하위 쿼리의 첫 번째 SELECT는 외부 쿼리에 따라 다릅니다. 즉, 하위 쿼리는 외부 쿼리의 결과에 따라 달라집니다.
from 목록에 포함된 하위 쿼리는 DERIVED(파생 테이블)로 표시됩니다. MySQL은 이러한 하위 쿼리를 재귀적으로 실행하고 결과를 임시 테이블에 저장합니다. Union 다음에 나타나면 Union으로 표시됩니다. from 절의 하위 쿼리에 Union이 포함되면 외부 선택은 Union 테이블에서
로 표시됩니다. Union merging 집합에서 선택 쿼리의 결과를 가져옵니다)
구체화된 테이블, 하위 쿼리가 쿼리와 연결되면 하위 쿼리 결과가 구체화된 임시 테이블에 저장되고 메인 테이블이 됩니다. 임시 테이블의 데이터를 기반으로 일치합니다.
UNION UNION의 두 번째 이후 쿼리문은 외부 쿼리에 따라 달라집니다
(3) 쿼리에서 별칭을 사용하는 경우 table
Type name
는 이것이 임시 테이블임을 나타내고, 다음 N은 실행 계획의 ID로 이 쿼리에서 결과가 생성됨을 나타냅니다.
N>과 유사하며 임시이기도 합니다. 이 결과는 통합 쿼리의 ID가 M,N인 결과 집합에서 나온 것입니다.

N>

이 행은 구체화된 하위 쿼리가 있는 행의 결과 ID N 값을 참조합니다.

(4)partitions

쿼리는 레코드의 파티션과 일치합니다. 파티션을 나누지 않은 테이블에는 NULL 값이 사용됩니다. NULL用于非分区表。

(5)type

依次从好到差:

system>const>eq_ref>ref>ref_or_null>range>index>ALL

除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。

我们自己创建一系列表来实验下:

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` int(11) NOT NULL,
  `sn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, 'sn123456', '衣服');

-- ----------------------------
-- Table structure for sku
-- ----------------------------
DROP TABLE IF EXISTS `sku`;
CREATE TABLE `sku`  (
  `id` int(11) NOT NULL,
  `goods_id` int(11) NOT NULL,
  `status` int(11) NOT NULL,
  `deleted` int(11) NOT NULL,
  `barcode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `index_2`(`name`) USING BTREE,
  INDEX `index_1`(`goods_id`, `status`, `deleted`, `barcode`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sku
-- ----------------------------
INSERT INTO `sku` VALUES (1, 1, 1, 0, 'kt123456', '黑色');

SET FOREIGN_KEY_CHECKS = 1;

system

表只有一行记录(等于系统表),这是 const 类型的特例,平时不会出现,这个也可忽略不计;

const

表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行记录,所以很快。 如果将主键置于 where 列表中,mysql 就能将该查询转换成一个常量;

EXPLAIN SELECT * FROM sku WHERE id=1;复制代码

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

eq_ref

唯一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配,常用于主键或唯一索引扫描;此类型通常出现在多表的 join 等值查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果,查询效率较高。

EXPLAIN SELECT * FROM sku,goods WHERE sku.goods_id=goods.id;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

ref

非唯一性索引扫描,返回匹配某个单独值得所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体;

EXPLAIN SELECT * FROM sku WHERE goods_id=1;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

ref_or_null

二级索引等值比较同时限定 is null 。

EXPLAIN SELECT * FROM sku WHERE name='123456' or name IS NULL;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

range

只检索给定范围的行,使用一个索引来选择行,key列显示使用哪个索引,一般就是在你的 where 语句中出现了 between、、in 等的查询;这种范围索引扫描比全表扫描要好,因为它只需要开始于索引的某一个点,结束于另一个点,不用扫描全部索引;

EXPLAIN SELECT * FROM sku WHERE id BETWEEN 1 and 10;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

index

index 和 all 区别为 index 类型只遍历索引树,这通常比 all 快,因为索引文件通常比数据文件小;也就是说虽然 all 和 index 都是读写表,但 index 是从索引中读取的,而 all 是从硬盘中读的;

EXPLAIN SELECT barcode FROM sku WHERE deleted=0;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

all

也就是全表扫描;

EXPLAIN SELECT * FROM sku WHERE deleted=0;

이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.

(6)possible_keys

查询可能使用到的索引都会在这里列出来。

(7)key

查询真正使用到的索引,select_typeindex_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

(8)key_len

key_len 表示该列计算查询中使用的索引的长度。例如:SELECT * FROM table where age = 1 and name like 'xx',假设 age 是 int 类型且不可为 null;name 是 varchar(20) 类型且可以为 null,编码为 utf8。若以这两个字段为索引查询,那么 key_len 的值为 4 + 3 * 20 + 2 + 1 = 67

(5) 유형🎜🎜🎜최상에서 최악까지: 🎜
🎜system>const > ;eq_ref>ref>ref_or_null>범위>색인 > ;ALL🎜
🎜 all 외에도 index_merge유형에서 인덱스를 사용할 수 있습니다. /code 제외 >, 다른 유형은 하나의 색인만 사용할 수 있습니다. 🎜🎜실험할 일련의 테이블을 직접 만들어 보겠습니다. 🎜🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜🎜 이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜rrreee

🎜system🎜

🎜테이블에는 레코드 행이 하나만 있습니다(시스템 테이블과 동일). 이는 다음의 특별한 경우입니다. const 유형이며 일반적으로 나타나지 않습니다. 이는 무시할 수도 있습니다. 🎜

🎜const🎜

🎜는 인덱스를 통해 한 번 발견되고 const가 사용된다는 의미입니다. 기본 키 또는 고유 인덱스를 비교합니다. 한 행의 레코드만 일치하므로 속도가 매우 빠릅니다. where 목록에 기본 키를 배치하면 mysql은 쿼리를 상수로 변환할 수 있습니다(🎜rrreee🎜🎜

🎜eq_ref🎜

🎜고유 인덱스 스캔, 각 인덱스 키마다 일치하는 테이블의 레코드는 단 하나이며 기본 키 또는 고유 인덱스 스캔에 자주 사용됩니다. 이 유형은 일반적으로 여러 테이블의 조인 동등 쿼리에 나타납니다. 즉, 이전 테이블의 각 결과에 대해 후속 테이블의 결과가 일치할 수 있으므로 쿼리 효율성이 더 높습니다. 🎜rrreee🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜🎜ref🎜🎜고유하지 않은 인덱스 스캔은 단일 값과 일치하는 모든 행을 반환합니다. 이는 본질적으로 단일 값과 일치하는 모든 행을 반환합니다. 그러나 일치하는 행을 여러 개 찾을 수 있으므로 찾기와 검색을 혼합해야 합니다. 🎜rrreee🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜

🎜ref_or_null🎜

🎜2차 인덱스 등 값 비교도 가능 null 입니다. 🎜rrreee🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜🎜range🎜🎜주어진 범위의 행만 검색하고 인덱스를 사용하여 행을 선택합니다. 키 열은 사용할 인덱스를 표시하며 일반적으로 where 문에 나타납니다. , in 등 사이의 쿼리는 전체 인덱스를 스캔하지 않고 인덱스의 특정 지점에서 시작하고 다른 지점에서 끝나기만 하면 되기 때문에 전체 테이블 스캔보다 낫습니다. 🎜rrreee 🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜

🎜index🎜

🎜index 및 all 차이점은 인덱스 유형은 인덱스 트리만 통과한다는 것입니다. 이는 일반적으로 인덱스 파일이 다음보다 작기 때문에 all보다 빠릅니다. 즉, 모든 인덱스는 읽기-쓰기 테이블이지만 인덱스는 모두 하드 디스크에서 읽혀지는 반면 인덱스는 인덱스에서 읽혀집니다. img.php.cn/upload/image/104/ 706/125/166635615814881이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다." title="166635615814881이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다." alt="이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다."/>🎜

🎜 all🎜

🎜즉, 전체 테이블 스캔 ;🎜rrreee🎜이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.🎜

🎜(6)possible_keys🎜🎜🎜 쿼리에 사용할 수 있는 인덱스가 여기에 나열됩니다. 🎜

🎜(7)key🎜🎜🎜실제로 사용된 인덱스를 쿼리합니다. select_typeindex_merge인 경우 나타날 수 있습니다. 세 개 이상의 색인이 있으면 다른 select_type 중 하나만 여기에 표시됩니다. 🎜

🎜(8)key_len🎜🎜🎜key_len은 쿼리 계산에 사용되는 인덱스의 길이를 나타냅니다. 예를 들면 다음과 같습니다. age = 1이고 이름이 'xx'인 FROM 테이블, age가 int 유형이고 null일 수 없다고 가정하면 name은 varchar(20) 유형이고 null일 수 있습니다. 그리고 인코딩은 utf8입니다. 이 두 필드가 인덱스 쿼리로 사용되는 경우 key_len 값은 4 + 3 * 20 + 2 + 1 = 67입니다. 구체적인 계산 규칙은 아래 표와 같습니다. 🎜

값 유형 값 이름 Description
String CHAR(n) n 바이트 길이

VARCHAR(n) utf8 인코딩인 경우, 3n + 2바이트이고, utf8mb4 인코딩인 경우 4n + 2바이트입니다.
숫자 유형 TINYINT 1바이트

SMALLINT 2바이트

MEDIUMINT 3바이트

INT 4바이트

BIGINT 8바이트
시간 유형 DATE 3바이트

TIMESTAMP 4바이트

DATETIME 8바이트
Field 속성 NULL 속성은 1바이트를 차지합니다. 필드가 NULL이 아닌 경우 해당 필드는 채워지지 않습니다.

(9)ref

상수 동등 쿼리인 경우 여기에 const가 표시됩니다. 연결 쿼리인 경우 구동 테이블의 실행 계획에 의 관련 필드가 표시됩니다. 조건이 표현식이나 함수를 사용하거나 조건 열이 내부 암시적 변환을 수행하는 경우 func로 표시될 수 있습니다. const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func

(10)rows

这里是执行计划中估算的扫描行数,不是精确值。

(11)filtered

使用explain extended时会出现这个列,5.7之后的版本默认就有这个字段,不需要使用explain extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。

(12)Extra

这个列可以显示的信息非常多,有几十种,常用的有:

1、distinct:在select部分使用了distinct关键字

2、no tables used:不带from字句的查询或者From dual查询。使用not in()形式子查询或not exists()运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。

3、using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。mysql中无法利用索引完成的排序操作称为“文件排序”。排序时无法使用到索引时,就会出现这个。常见于order by语句中,需要尽快优化

4、using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。

5、using join buffer(block nested loop),using join buffer(batched key accss)5.6.x之后的版本优化关联查询的BNLBKA特性。主要是减少内表的循环数量以及比较顺序地扫描查询。

6、using sort_union,using_union,using intersect,using sort_intersection:

  • using intersect:表示使用and的各个索引的条件时,该信息表示是从处理结果获取交集
  • using union:表示使用or连接各个使用索引的条件时,该信息表示从处理结果获取并集
  • using sort_union和using sort_intersection:与前面两个对应的类似,只是他们是出现在用andor查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。

7、using temporary:表示使用了临时表存储中间结果。临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_tableused_tmp_disk_table才能看出来。常见于order by和分组查询group bygroup by一定要遵循所建索引的顺序与个数。需要尽快优化

8、using where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性(index condition pushdown,索引下推),可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量。extra列显示using index condition

9、firstmatch(tb_name)5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个

10、loosescan(m..n)5.6.x之后引入的优化子查询的新特性之一,在in()

(10)rows

여기에는 정확한 값이 아닌 실행 계획의 예상 스캔 행 수가 나와 있습니다.

(11)filtered

🎜🎜이 열은 explain Extended를 사용할 때 표시되며, 5.7 이후 버전은 기본적으로 이 필드를 사용하면 확장 설명을 사용할 필요가 없습니다. 이 필드는 스토리지 엔진에서 반환된 데이터가 서버 계층에서 필터링된 후 쿼리를 충족하는 나머지 레코드의 비율을 나타냅니다. 이는 특정 레코드 수가 아닌 백분율입니다. 🎜

🎜(12) Extra🎜🎜🎜이 열은 많은 정보를 표시할 수 있으며 수십 개가 있으며 일반적으로 사용되는 정보는 다음과 같습니다. 🎜🎜🎜1, independent🎜: ​​에서 <code>distinct 키워드는 >select 부분🎜🎜🎜2에서 사용됩니다. 테이블이 사용되지 않습니다🎜: from 또는 가 없는 쿼리 이중 code>쿼리에서. <code>not in() 형식 하위 쿼리나 안티 조인이라고 하는 not presents() 연산자의 조인 쿼리를 사용하세요. 즉, 일반 조인 쿼리는 내부 테이블을 먼저 쿼리한 후 외부 테이블을 쿼리하는 반면, 안티 조인 쿼리는 외부 테이블을 먼저 쿼리한 후 내부 테이블을 쿼리합니다. 🎜🎜🎜3. using filesort🎜: 설명 mysql은 테이블의 인덱스 순서대로 읽는 대신 외부 인덱스를 사용하여 데이터를 정렬합니다. mysql에서 인덱스를 사용하여 완료할 수 없는 정렬 작업을 "파일 정렬"이라고 합니다. 이는 정렬 중에 인덱스를 사용할 수 없을 때 발생합니다. order by 문에서 흔히 볼 수 있으며 최대한 빨리 최적화해야 합니다🎜🎜🎜4. index 사용🎜: 쿼리할 때 테이블로 돌아갈 필요가 없으며 쿼리 데이터를 인덱스를 통해 직접 얻습니다. 🎜🎜🎜5. 조인 버퍼(블록 중첩 루프) 사용, 조인 버퍼(일괄 키 accss) 사용🎜: 5.6.x 이상 버전에서는 관련 쿼리에 대해 BNL을 최적화합니다. BKA 기능. 주요 목적은 내부 테이블의 루프 수를 줄이고 쿼리를 순차적으로 스캔하는 것입니다. 🎜🎜🎜6. using sort_union, using_union, using intersect, using sort_intersection: 🎜🎜
  • using intersect: and를 사용하여 각 인덱스의 조건을 나타낼 때 이 정보는 결과 획득 교차점에서 처리
  • Union 사용: 인덱스를 사용하여 조건을 연결하기 위해 or를 사용할 때 처리 결과에서 Union을 얻었음을 나타내는 정보입니다.
  • sort_union 사용 및 sort_intersection 사용: andor를 사용하여 많은 양의 정보를 쿼리할 때 나타나는 점을 제외하면 이전 두 가지와 유사합니다. 먼저 쿼리한 다음 정렬하고 병합한 후에만 레코드를 읽고 반환할 수 있습니다.
🎜🎜7. using temporary🎜: 중간 결과를 저장하는 데 임시 테이블이 사용됨을 나타냅니다. 임시 테이블은 메모리 임시 테이블일 수도 있고 디스크 임시 테이블일 수도 있습니다. 실행 계획에서는 status 변수, used_tmp_table, used_tmp_disk_table을 확인해야 합니다. 나오시면 됩니다. 일반적으로 order by 및 그룹 쿼리 group by에 사용됩니다. 그룹화 기준은 생성된 색인의 순서와 개수를 따라야 합니다. 가능한 한 빨리 최적화해야 합니다🎜🎜🎜8. using where🎜: 스토리지 엔진에서 반환된 모든 레코드가 쿼리 조건을 충족하지 않으며 서버 계층에서 필터링해야 함을 나타냅니다. 쿼리 조건은 제한 조건과 검사 조건으로 구분됩니다. 5.6 이전에는 스토리지 엔진이 제한 조건에 따라 데이터를 스캔하고 반환할 수만 있었으며, 이후에는 서버 계층이 검사 조건에 따라 실제로 쿼리와 일치하는 데이터를 필터링하여 반환합니다. 5.6.x5.6.x 이후 ICP 기능(인덱스 조건 푸시다운, 인덱스 푸시다운)을 지원합니다. 검사 조건 및 제한 사항을 충족하지 않는 스토리지 엔진 계층은 데이터를 직접 읽지 않으므로 스토리지 엔진에서 검색하는 레코드 수가 크게 줄어듭니다. extra 열에는 🎜using index Condition🎜🎜🎜🎜9, firstmatch(tb_name)🎜이 표시됩니다. 이는 일반적으로 볼 수 있는 5.6.x에 도입된 최적화 하위 쿼리의 새로운 기능 중 하나입니다. in where 절에는 in() 유형의 하위 쿼리가 포함되어 있습니다. 내부 테이블의 데이터 양이 상대적으로 많으면 이런 일이 발생할 수 있습니다🎜🎜🎜10.loosescan(m..n)🎜: 5.6.x 이후 도입된 최적화 하위 쿼리의 새로운 기능 중 하나 , in in() 유형 하위 쿼리에서 하위 쿼리가 중복 레코드를 반환하는 경우 이러한 현상이 발생할 수 있습니다🎜🎜🎜4. 주요 초점을 설명하세요🎜🎜🎜일반적으로 몇 개의 열에만 주의하면 됩니다. 결과: 🎜
열 이름 Remarks
type 이 쿼리 테이블 연결 유형, 여기에서 이 쿼리의 대략적인 효율성을 확인할 수 있습니다.
key 최종 선택된 인덱스, 그렇지 않은 경우 인덱싱 측면에서 볼 때 이 쿼리의 효율성은 일반적으로 매우 낮습니다.
key_len 이 쿼리에서 결과 필터링에 사용된 인덱스의 실제 길이
rows 스캔해야 할 예상 레코드 수 , 스캔해야 할 예상 레코드 수more 작을수록 좋음
Extra 추가 추가 정보는 주로 filesort 사용임시 사용의 두 가지 상황인지 확인합니다. 발생Using filesortUsing temporary这两种情况

再来看下Extra列中需要注意出现的几种情况:

关键字 备注
Using filesort 将用外部排序而不是按照索引顺序排列结果,数据较少时从内存排序,否则需要在磁盘完成排序,代价非常高,需要添加合适的索引
Using temporary 需要创建一个临时表来存储结果,这通常发生在对没有索引的列进行GROUP BY时,或者ORDER BY里的列不都在索引里,需要添加合适的索引
Using index 表示MySQL使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据,这是比较好的结果之一。注意不要和type中的index类型混淆
Using where 通常是进行了全表/全索引扫描后再用WHERE子句完成结果过滤,需要添加合适的索引
Impossible WHERE Where子句判断的结果总是false而不能选择任何数据,例如where 1=0,无需过多关注
Select tables optimized away 使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询,例如MIN()MAX()
다시 살펴보겠습니다. Extra 열에 주의해야 할 몇 가지 상황이 있습니다:

🎜Keywords🎜🎜Remarks🎜🎜🎜🎜🎜 🎜filesort🎜🎜를 사용하면 결과를 인덱스 순서로 정렬하는 대신 외부 정렬을 사용하게 됩니다. 데이터가 적을 경우 메모리에서 정렬해야 하며, 그렇지 않으면 디스크에서 정렬을 완료해야 하므로 비용이 많이 듭니다. 🎜적절한 인덱스를 추가해야 합니다🎜 🎜🎜🎜🎜임시 사용하기🎜🎜결과를 저장하기 위해 임시 테이블을 만들어야 하는데, 이는 일반적으로 인덱스가 없을 때 발생합니다. GROUP BY의 열을 수행할 때 또는 ORDER BY가 인덱스에 모두 포함되어 있지 않으므로 적절한 인덱스를 추가해야 합니다🎜🎜🎜🎜🎜인덱스🎜🎜를 사용한다는 것은 MySQL가 전체 테이블 스캔을 피하기 위해 커버링 인덱스를 사용한다는 것을 의미합니다. 테이블에서 데이터를 두 번 검색할 필요가 없습니다. 이는 더 나은 결과 중 하나입니다. type🎜🎜🎜🎜where 사용🎜🎜일반적으로 WHERE 절은 결과 필터링을 완료합니다 🎜적절한 인덱스를 추가해야 합니다🎜🎜🎜🎜🎜Impossible WHERE🎜🎜<code>Where 절의 판단 결과는 항상 false이며 데이터를 선택할 수 없습니다. , 예를 들어 where 1=0, 너무 많은 주의를 기울일 필요가 없습니다🎜🎜🎜🎜최적화되지 않은 테이블을 선택하세요🎜🎜특정 집계 함수를 사용하여 인덱스가 있는 필드에 액세스하면 최적화 프로그램이 직접 위치를 찾습니다. 인덱스를 통해 필수 필드를 한 번에 데이터 행이 MIN()MAX()와 같은 전체 쿼리를 완성하는데, 이 역시 더 나은 결과 중 하나입니다🎜🎜🎜🎜🎜[관련 추천: 🎜 mysql 동영상 튜토리얼🎜]🎜

위 내용은 이 기사는 MySQL 실행 계획을 빠르게 이해하는 데 도움이 될 것입니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제