mysql에 대한 자세한 설명, 유형 성능 순위 시스템>const>eq_ref>ref>fulltext>range>index>ALL, 인덱스 실패 상황 요약(미완성)

1. explain설명

여기에 이미지 설명을 삽입하세요.

일련번호 목록 설명하다
1 ID 대규모 쿼리 문에서 각 SELECT 키워드는 고유 ID에 해당합니다.
2 select_type SELECT 키워드에 해당하는 쿼리 유형
테이블 테이블 이름
4 파티션 일치하는 파티션 정보
5 종류 ★ 단일 테이블에 대한 액세스 방법
6 가능한_키 가능한 인덱스
7 열쇠 실제 사용된 인덱스
8 key_len ★ 사용된 실제 인덱스 길이
9 심판 인덱스 열 동등 쿼리 사용 시, 동등성을 위한 인덱스 열과 일치하는 개체 정보입니다.
10 행 ★ 읽을 예상 레코드 수
11 거르는 검색 조건으로 필터링한 후 테이블에 남아 있는 레코드의 비율
12 추가 ★ 몇 가지 추가 정보

1.1.설명 type_

  1. 최고부터 최악까지 다음 표에 나와 있습니다.
  2. 굵은 글씨가 더 중요합니다.
  3. SQL 성능 최적화의 목표는 최소한 범위 수준에 도달하는 것입니다. 요구 사항은 참조 수준(바람직하게는 consts 수준)입니다. (Alibaba 개발 매뉴얼에 필요함)
일련번호 목록 설명하다
1.1 체계 테이블에 레코드가 하나만 있고 해당 테이블에서 사용하는 MyISAM, Memory 등 스토리지 엔진의 통계가 정확한 경우
1.2 const 기본 키 또는 고유 인덱스 열과 상수를 기반으로 등가 매칭을 수행할 때 단일 테이블에 대한 액세스 방법은 다음과 같습니다.const
1.3 eq_ref 쿼리 연결 시, Primary Key 또는 Unique Secondary Index 컬럼의 동일값 매칭을 통해 Driven Table에 접근하는 경우(Primary Key 또는 Unique Secondary Index가 Joint Index인 경우 모든 인덱스 컬럼이 동일해야 함) 값 비교) , 구동 테이블에 대한 액세스 방법은 다음과 같습니다.eq ref
1.4 심판 일반 보조 인덱스 컬럼과 상수 간의 동등 매칭을 통해 테이블을 쿼리할 때 테이블에 대한 액세스 방법은 다음과 같습니다.ref
2.1 전문 약간
2.2 ref_or_null 공통 보조 인덱스에 대해 동등한 일치 쿼리를 수행할 때 인덱스 열의 값도 NULL값이 될 수 있으며, 테이블에 대한 액세스 방법은 다음과 같습니다.ref_or_null
2.3 index_merge 단일 테이블 액세스 방법을 사용할 때 일부 시나리오에서는 , 및 의 세 가지 인덱스 병합 방법을 사용하여 Intersection쿼리 Unionsort-Union실행할 수 있습니다.
2.4 고유_하위 쿼리 IN쿼리 최적화 프로그램이 하위 쿼리를 하위 쿼리 IN로 변환하기 로 결정하고 하위 쿼리가 동등한 일치를 위해 고유 인덱스를 사용할 수 있는 경우 하위 쿼리가 포함된 일부 쿼리 문에 대한 것입니다 .EXISTS
2.5 index_subquery IN쿼리 최적화 프로그램이 하위 쿼리를 하위 쿼리 IN로 변환하기 로 결정하고 하위 쿼리가 동등한 일치를 위해 일반 인덱스를 사용할 수 있는 경우 하위 쿼리가 포함된 일부 쿼리 문에 대한 것입니다 .EXISTS
2.6 범위 특정 레코드를 얻기 위해 색인을 사용하는 경우 范围区间'범위' 액세스 방법을 사용할 수 있습니다.
3.1 색인 인덱스 커버리지를 사용할 수 있지만 모든 인덱스 레코드를 스캔해야 하는 경우 테이블의 액세스 방법은 다음과 같습니다.index
3.2 모두 인덱스를 사용하지 않는 상황(다양한 인덱스 실패 상황)

1.1.1.SQL 요약

-- 结果值从最好到最坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,最好是 consts级别。(阿里巴巴开发手册要求)
-- 1.等值匹配
-- 1.1.`system`。当表中只有一条记录并且该表使用的在储引擎的统计数据是精确的,比如MyISAM、Memory
explain select * from demo where id = '1';
-- 1.2.`const`。当我们根据主键或者唯一索引列与常数进行等值匹配时,对单表的访问方法就是`const`
explain select * from demo where id2 = '1';
-- 1.3.`eq_ref`。在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是`eq ref`
explain select * from demo a,demo b where a.id2  = b.id2;
-- 1.4.`ref`。当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是`ref`
explain select * from demo where id3 = '1';
explain select * from demo where id2 is null;                               -- 对比上面的1.2.
explain select * from demo a,demo b where a.id3 = b.id3;                    -- 对比上面的1.3.
-- 2.模糊、范围查询等
-- 2.1.`fulltext`略
-- 2.2.`ref_or_null`。当对普通二级索引进行等值匹配查询,该索引列的值也可以是`NULL`值时,那么对该表的访问方法就可能是`ref_or_null`
explain select * from demo where id2 = '1' or id2 is null;		            -- 如果字段有not null约束,则为const(唯一索引时)、ref(普通索引时)
explain select * from demo where id3 = '1' or id3 is null;		            -- 如果字段有not null约束,则为const(唯一索引时)、ref(普通索引时)
-- 2.3.`index_merge`。单表访问方法时在某些场景下可以使用`Intersection`、`Union`、`sort-Union`这三种索引合并的方式来执行查询
explain select * from demo where id2 = '1' or id3 = '2';
explain select * from demo where id2 = '1' or id3 in ('2','3');
-- 2.4.`unique_subquery`。是针对在一些包含`IN`子查询的查询语句中,如果查询优化器决定将`IN`子查询转换为`EXISTS`子查询,而且子查询可以使用到唯一索引进行等值匹配的话。
explain select * from demo a where id4 in (select id2 from demo where id4 = a.id4) or id4 ='1';
-- 2.5.`index_subquery`。是针对在一些包含`IN`子查询的查询语句中,如果查询优化器决定将`IN`子查询转换为`EXISTS`子查询,而且子查询可以使用到普通索引进行等值匹配的话。
explain select * from demo a where id4 in (select id3 from demo where id4 = a.id4) or id4 ='1';
-- 2.6.`range`。如果使用索引获取某些`范围区间`的记录,那么就可能使用到`range '访问方法
explain select * from demo where id in ('1','2');
explain select * from demo where id > '1';
explain select * from demo where id between '1' and '2';
explain select * from demo where id like '1%';						        -- 注意:id为数字类型,索引失效
-- 3.全表扫描
-- 3.1.`index`。当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是`index`
explain select distinct id3 from demo;                                      --  如果id3有大量重复数据时,则为range
explain select id from demo;
-- 3.2.`ALL`各种未使用索引(索引失效情况)的情况
explain select distinct id4 from demo;
explain select id4 from demo;
explain select * from demo where id is not null;

1.1.2 데이터 테스트 생성(java)

1.1.2.1.코드 작성

  1. 테이블 생성
drop table if exists demo;
create table demo
(
    `id`  bigint not null auto_increment comment '8个字节。单列索引、聚簇索引(一级索引)、主键索引。',
    `id2` bigint default null comment '8个字节。单列索引、非聚簇索引(二级索引)、唯一索引。',
    `id3` bigint default null comment '8个字节。单列索引、非聚簇索引(二级索引)、普通索引。',
    `id4` bigint default null comment '8个字节。无索引。',
    primary key (`id`),
    unique key `id2` (`id2`),
    key `id3` (`id3`)
) default charset = gbk comment ='演示';

  1. 1000개의 데이터를 일괄 삽입합니다. 자세한 Java 코드는 코드 클라우드 lishuoboy-mysql을 참조하세요.
@Slf4j
@RestController
public class IndexController {
    
    
    @Autowired
    DataSource ds;
    @Autowired
    DemoService demoService;

    @GetMapping("/saveBatchDemo/{count}")
    Object saveBatchDemo(@PathVariable int count) {
    
    
        TimeInterval timeInterval = new TimeInterval();
        List<Demo> demoList = new ArrayList(count);
        for (long i = 1; i <= count; i++) {
    
    
            Demo demo = Demo.builder()
                    .id(i).id2(i).id3(i).id4(i)
                    .build();
            demoList.add(demo);
        }
        //持久化。
        demoService.saveBatch(demoList);
        log.warn("总用时=={}s", timeInterval.intervalSecond());
        return demoService.count();
    }
}
  1. 요청 보내기

http://localhost:8080/saveBatchDemo/1000

2. 인덱스 실패

-- 对于所有本应该走索引的,当mysql发现通过索引扫描的行记录数超过全表的10%-30%时,优化器可能会放弃走索引,自动变成全表扫描
-- 1. =走索引,!=、<>也走索引
explain select id2 from user where varchar_short4  = '0';            						--  = 范围小,肯定走索引。ref。key_len=11
explain select id2 from user where varchar_short4  = '0000';										--  = 范围大,肯定走索引。ref
explain select id2 from user where varchar_short4 != '0000';										-- != 范围小,    走索引。range
explain select id2 from user where varchar_short4 != '0';												-- != 范围大,  不走索引。
-- 2. <、>、>=、<= 和 between、not between均走索引
explain select id2 from user where varchar_short4 <=  '0';   								  	-- <= 范围小,  走索引。range
explain select id2 from user where varchar_short4 <= '0000';   									-- <= 范围大,不走索引。
explain select id2 from user where varchar_short4 	  between 'a' and 'z';  		--     between 范围小,  走索引。range
explain select id2 from user where varchar_short4 		between '0' and 'z';			--     between 范围大,不走索引。
explain select id2 from user where varchar_short4 not between '0' and 'z';			-- not between 范围小,  走索引。range
explain select id2 from user where varchar_short4 not between 'a' and 'z';			-- not between 范围大,不走索引。
-- 3.in走索引,not in走索引,in 1个值时同=。in 1个变量,自动转为=。
explain select id2 from user where varchar_short4     in ('0');									--     in 范围小,肯定走索引。ref
explain select id2 from user where varchar_short4     in ('0000');							--     in 范围大,肯定走索引。ref
explain select id2 from user where varchar_short4     in ('0','1');							--     in 范围小,    走索引。range
explain select id2 from user where varchar_short4     in ('0000','1');					--     in 范围大,  不走索引。
explain select id2 from user where varchar_short4 not in ('0000');	   					-- not in 范围小,    走索引。range
explain select id2 from user where varchar_short4 not in ('0');			    				-- not in 范围大,  不走索引。
-- 4.exists走索引,not exists不走索引【需细化】
explain select id2 from user o where exists (select 1 from user where id =o.id and varchar_short4 ='0');		--     exists范围小,    走索引。ref
explain select id2 from user o where exists (select * from user where varchar_short4 =o.varchar_short4 and varchar_short4 ='0');	--     exists范围小,   走索引。ref
explain select id2 from user o where exists (select * from user where varchar_short4 =o.varchar_short4 and varchar_short4 ='0000');	--     exists范围大,  不走索引。
explain select id2 from user o where not exists (select id2 from user where varchar_short4 =o.varchar_short4 and varchar_short4 ='0000');		-- not exists肯定不走索引。
-- 5.null,同=
explain select id2 from user where varchar_short6 is     null;									-- is     null 范围小,  走索引。ref
explain select id2 from user where varchar_short5 is     null;									-- is     null 范围大,  走索引。ref
explain select id2 from user where varchar_short5 is not null;									-- is not null 范围小,  走索引。range,
explain select id2 from user where varchar_short6 is not null;									-- is not null 范围大,不走索引。
-- like 
explain select id2 from user where varchar_short4     like 'a';									--        like前缀 范围小,  走索引。range
explain select id2 from user where varchar_short4     like '0000';							--        like前缀 范围大,不走索引。
explain select id2 from user where varchar_short4     like 'a%';								--        like前缀 范围小,  走索引。range
explain select id2 from user where varchar_short4     like '0000%';							--        like前缀 范围大,不走索引。
explain select id2 from user where varchar_short4     like '%a';								--        like后缀 范围小,不走索引。
explain select id2 from user where varchar_short4 not like '0000%';							--        like前缀 范围小,不走索引。
-- distinct
explain select distinct varchar_short4 from user;																-- 范围小,走索引。range
explain select distinct varchar_mid2 from user;																						-- 范围大,走索引。range
explain select distinct varchar_short3 from user;
-- order by
explain select id2 from user order by varchar_short4 limit 1000;								-- 走索引。index
explain select id2 from user order by varchar_short3 limit 1000;
-- group by
explain select varchar_short4 from user group by varchar_short4 limit 1000;			-- 走索引。range
explain select varchar_short3 from user group by varchar_short3 limit 1000;
-- having。having是group by后,属于聚合函数,肯定不走索引
explain select varchar_short2 from user group by varchar_short2 having varchar_short2 = '00';			-- 不走索引
explain select varchar_short1 from user group by varchar_short1 having varchar_short1 = '00';			
-- and/or
explain select id2 from user where varchar_short4 = '0' and varchar_short5 = '0';		-- 走索引。index_merge 。key_len=11,11
explain select id2 from user where varchar_short4 = '0' or  varchar_short5 = '0';		-- 走索引。index_merge 。key_len=11,11
-- 类型隐式转换
explain select id2 from user where varchar_short4 = '11';						-- 无类型转换,  走索引
explain select id2 from user where varchar_short4 =  11 ;						-- 有类型转换,不走索引。对于varchar,查的数据也是错的
explain select id2 from user where id = '11';												-- 无类型转换,  走索引
explain select id2 from user where id =  11;												-- 无类型转换,  走索引
-- 函数、运算、两列比较
explain select id2 from user where lower(varchar_short4) = '00';		-- 函数,不走索引
explain select id2 from user where varchar_short4 || '0' = '00';		-- 函数,不走索引
explain select id2 from user where id + 1 = 100;										-- 运算,不走索引
explain select id2 from user where id = 100 - 1;										-- 不运算,走索引
explain select id2 from user where varchar_short4 = varchar_short5;	-- 两列比较,不走索引
-- 联合索引。最左匹配原则。与where 后面的字段顺序无关,sql优化器会自动调整。其它情况与单字段索引类type、失效原则一致
explain select id2 from user2 where varchar_short7 = '0' and varchar_short8 = '0' and varchar_short9 = '0';				--   走索引,key_len=33
explain select id2 from user2 where varchar_short9 = '0' and varchar_short8 = '0' and varchar_short7 = '0';				--   走索引,key_len=33
explain select id2 from user2 where varchar_short9 = '0' and varchar_short8 = '0' and varchar_short7 = '0';				--   走索引,key_len=33
explain select id2 from user2 where varchar_short7 = '0' and varchar_short8 = '0';																--   走索引,key_len=22
explain select id2 from user2 where varchar_short7 = '0' and varchar_short9 = '0';																--   走索引,key_len=11
explain select id2 from user2 where varchar_short7 = '0';																													--   走索引,key_len=11
explain select id2 from user2 where varchar_short8 = '0' and varchar_short9 = '0';																-- 不走索引
explain select id2 from user2 where varchar_short8 = '0';																													-- 不走索引
explain select id2 from user2 where varchar_short9 = '0';																													-- 不走索引
explain select id2 from user2 where varchar_short7 in( '0','1');																									--   走索引,key_len=11
explain select id2 from user2 where varchar_short7 in( '0','1') and varchar_short8 = '0' and varchar_short9 = '0';--   走索引,key_len=33
explain select id2 from user2 where varchar_short7 > '1';																													--   走索引,key_len=11
explain select id2 from user2 where varchar_short7 > '1'        and varchar_short8 = '0' and varchar_short9 = '0';--   走索引,key_len=33
explain select id2 from user2 where varchar_short7 like '1%'																											--   走索引,key_len=11
explain select id2 from user2 where varchar_short7 like '1%' and varchar_short8 = '0' and varchar_short9 = '0';		--   走索引,key_len=33
explain select id2 from user2 where varchar_short7 = '0' or  varchar_short8 = '0';																-- 不走索引

explain select id2 from user ;

explain select * from user where bigint2 = 1 limit 1;
explain select distinct id2 from user where id2  > '1';
explain select id2 from user limit 100,1;

select * from user;

explain select id2 from user where id2   = '1';            										--  =范围小,肯定走索引。const
explain select id2 from user where id2  != '1';            										--  =范围小,肯定走索引。const


Supongo que te gusta

Origin blog.csdn.net/lishuoboy/article/details/132255459
Recomendado
Clasificación