데이터베이스 테이블 구조 :
사용자 테이블 (생성 ID INT 기본 키 , 이름 varchar (20), 성 VARCHAR (5), 인덱스 (명) ) = 엔진 이노 단계;
ID, 이름을 선택 어디에 이름 = 'shenjian' 를 선택 ID, 이름, 성별 어디 이름 = 'shenjian'
검색 프로세스가 완전히 다른 이유 속성을, 멀티 쿼리?
다시 테이블에 쿼리가 무엇입니까?
커버 인덱스는 무엇입니까?
어떻게 인덱스 덮개를 달성하기 위해?
어떤 시나리오는 SQL 인덱스 범위를 사용하여 최적화 할 수있다?
이 컨텐츠를 공유하는 오늘이다,이 중.
음성 해설 :이 시험은 MySQL5.6 - 이노을 기반으로합니다.
첫째, 쿼리는 테이블에 다시 무엇인가?
그것은 첫째 이노, 이야기 이노에서 인덱스를 달성해야하며, 두 개의 인덱스가 있습니다 :
-
클러스터 된 인덱스 (클러스터 인덱스)
-
일반 인덱스 (보조 인덱스)
InnoDB는 인덱스와 일반 인덱스의 차이점은 무엇입니까 클러스터?
InnoDB는 인덱스를 클러스터 리프 노드 저장 행 , 따라서 하나의 클러스터 된 인덱스 이노 될해야합니다 :
PK 테이블이 정의되는 경우 (1), PK는 클러스터 된 인덱스이고;
(2) 표 PK 정의되지 않으면, 최초의 열은 NULL 고유 클러스터 인덱스 아니다;
(3) 그렇지 않으면, InnoDB는 클러스터 된 인덱스로 숨겨진 행 ID를 생성합니다;
성우 : 매우 빠른 그래서 PK 쿼리는 직접 행을 위치.
이노 일반 인덱스 의 리프 노드는 기본 키 값을 저장합니다 .
VO는 : 대신 기록 헤드 포인터 메모리 행의 레코드 포인터 인덱스 리프 노드 저장의 MyISAM, 그합니다.
위시리스트와 밤나무, 경우 :
t (PK 번호, 이름 KEY, 섹스, 플래그);
성우 : ID는 클러스터 된 인덱스는, 이름이 일반 인덱스입니다.
표는 네 개의 레코드가 있습니다 :
1 shenjian, m하는
3 zhangsan, m하는
5, 리시, I,
9 wangwu, F, B
B + 트리 인덱스 두 사람은 위의 그림과 같습니다
PK, 클러스터 된 인덱스의 리프 노드를 저장 행 (1) ID;
그 열쇠, 일반 인덱스의 리프 노드를 저장 PK 값, 즉, ID로서 (2) 이름;
일반 인덱스는 직접 행을 배치 할 수없는, 그 이후 쿼리 프로세스의 일반적인 인덱스는 어떻게 가지입니까?
일반적으로 이 두 번 인덱스 스캔 코드 트리가 필요합니다 .
예를 들면 :
선택 * t에서 여기서 이름 = '리시';
그것은을 구현하는 방법입니까?
핑크 경로 코드는 두 번 인덱스 트리를 검사 할 필요가있다 :
(1) 기본 키 값을 식 (5)에 제 통상 인덱스 위치;
(2) 클러스터 된 인덱스 열을 위치시키는 단계;
이 호출됩니다 다시 테이블 쿼리 의 성능은 인덱스 트리를 통해 스윕보다 낮은 먼저 선 레코드를 찾을 후 기본 키 값을 찾은.
둘째, 인덱스 덮개 것입니다 (인덱스 취재는) ?
금액은, 집주인은 MySQL의 공식 웹 사이트에서이 개념을 찾지 못했습니다.
성우 : 엄격한 장학금, 맞죠?
SQL-Server는 인수의 공식 웹 사이트를 빌려.
MySQL의 공식 웹 사이트, 유사한 문이 설명 쿼리 계획 최적화 장에 나타납니다 출력 추가 필드 설명 인덱스를 사용하여 인덱스가 범위를 트리거 할 수 있습니다 .
이 SQL-Server 또는 MySQL의 공식 웹 사이트의 공식 웹 사이트가 있는지 여부, 우리는 표현이 있습니다 만에 복귀하지 않고 SQL 인덱스 트리의 모든 필요한 데이터 열을 얻을 수 있어야합니다 빨리.
셋째, 어떻게 인덱스 덮개를 달성하기 위해?
일반적인 방법은 다음과 같습니다 필드가 쿼리, 공동 색인의 설립 가고 .
아직도 예 전에 :
사용자 테이블 (생성 ID INT 기본 키 , 이름 varchar (20), 성 VARCHAR (5), 인덱스 (명) ) = 엔진 이노 단계;
첫 번째 SQL 문 :
선택 아이디, 사용자의 이름이 어디에 이름 = 'shenjian';
당신은 인덱스 리프 노드에 저장하는 1 차 키 ID, ID와 이름, 나무 이름으로 색인을 생성 할 수있는 이름 색인을 칠 수 테이블로 복귀하지 않고 인덱스 범위, 높은 효율과 일치.
음성을 통해, 추가 : 은 Using 인덱스 .
두 번째 SQL 문 :
선택 ID, 이름, 성별 사용자의 위치를 이름 = 'shenjian';
能够命中name索引,索引叶子节点存储了主键id,但sex字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取sex字段,效率会降低。
画外音,Extra:Using index condition。
如果把(name)单列索引升级为联合索引(name, sex)就不同了。
create table user ( id int primary key, name varchar(20), sex varchar(5), index(name, sex) )engine=innodb;
可以看到:
select id,name ... where name='shenjian';
select id,name,sex ... where name='shenjian';
都能够命中索引覆盖,无需回表。
画外音,Extra:Using index。
四、哪些场景可以利用索引覆盖来优化SQL?
场景1:全表count查询优化
原表为:
user(PK id, name, sex);
直接:
select count(name) from user;
不能利用索引覆盖。
添加索引:
alter table user add key(name);
就能够利用索引覆盖提效。
场景2:列查询回表优化
select id,name,sex ... where name='shenjian';
这个例子不再赘述,将单列索引(name)升级为联合索引(name, sex),即可避免回表。
场景3:分页查询
select id,name,sex ... order by name limit 500,100;
将单列索引(name)升级为联合索引(name, sex),也可以避免回表。
InnoDB聚集索引普通索引,回表,索引覆盖
出处:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962609&idx=1&sn=46e59691257188d33a91648640bcffa5&chksm=bd2d092d8a5a803baea59510259b28f0669dbb72b6a5e90a465205e9497e5173d13e3bb51b19&mpshare=1&scene=1&srcid=&sharer_sharetime=1564396837343&sharer_shareid=7cd5f6d8b77d171f90b241828891a85f&key=abd60b96b5d1f2e52ca45314fb2c95a67fad7a457fe265562eb51a1c026389d3f28c52359f96e920368ab44a5d08ebcbbe2ded474be2ba70731ed8b5dcc5dd68cc0eceb4989a74fb04e5055c78af8d38&ascene=1&uin=MTAwMjA4NTM0Mw%3D%3D&devicetype=Windows+7&version=62060739&lang=zh_CN&pass_ticket=tXA4xc7SZYamLpGZz5B6JwJa1ZRvZ4bRlmzFhXwEKeOfloPLulU0O80gsIQUiONb