단일 열 인덱스 또는 공동 인덱스에 관계없이 인덱스는 독립적인 B+ 인덱스 트리에 해당합니다. 인덱스 트리 노드에는 다음만 포함됩니다.
인덱스의 필드 값
프라이머리 키 값
인덱스 트리에 따른 조건에 따라 필요한 데이터를 찾았다고 해도 인덱스에 있는 여러 필드의 값과 기본 키 값만 있을 뿐입니다. select *
를 수행하면 여전히 다른 필드를 얻으려면 테이블로 돌아가서 클러스터형 인덱스의 기본 키에 따라 클러스터형 인덱스를 검색해야 합니다. index는 데이터 페이지입니다. 데이터 페이지를 찾아야만 데이터 행의 모든 필드 값을 읽을 수 있습니다.
따라서 select *
,那就还得其他字段,就需回表,根据主键到聚簇索引里找,聚簇索引的叶节点是数据页,找到数据页才能把一行数据所有字段值读出来。
所以类似
select * from table order by xx1,xx2,xx3
得从联合索引的索引树里按序取出所有数据,接着对每条数据都走一个主键的聚簇索引查找,性能不高。
有时MySQL
执行引擎可能认为,你要是类似
select * from table order by xx1,xx2,xx3
相当于得把联合索引和聚簇索引,两个索引的所有数据都扫描一遍,那还不如不走联合索引,直接全表扫描得了,这样就只需扫描一个主键索引。
但若形如:
select * from table order by xx1,xx2,xx3 limit 10
那执行引擎就知道你先扫描联合索引的索引树,拿到10条数据,接着对10条数据在聚簇索引里查找10次即可,那就还是会走联合索引。
覆盖索引不是一种索引,只是一种基于索引查询的方式,即针对类似
select xx1,xx2,xx3 from table order by xx1,xx2,xx3
仅需联合索引里的几个字段的值,那就只需扫描联合索引的索引树,无需回表找其它字段,这种查询方式就是覆盖索引。
所以当你使用联合索引时,注意是否可能会导致大量回表到聚簇索引,若回表聚簇索引的次数太多,可能就直接给你做成全表扫描而不走联合索引了。
尽可能还是在SQL里指定你仅需要的字段,而不要暴力select *
,最好直接走覆盖索引。
即使无可避免地要回表,你也尽可能用limit
、 where
rrreee
MySQL
실행 엔진이 🎜rrreee🎜 같은 사람이라면 조인트 인덱스와 클러스터드 인덱스의 모든 데이터를 스캔하는 것과 같다고 생각할 수도 있으니 떠나지 않는 것이 좋습니다. 조인트 인덱스의 경우 전체 테이블을 직접 스캔할 수 있으므로 기본 키 인덱스 하나만 스캔하면 됩니다. 🎜🎜🎜그러나 다음과 같다면: 🎜🎜rrreee🎜그러면 실행 엔진은 먼저 공동 인덱스의 인덱스 트리를 스캔하여 10개의 데이터를 얻은 다음 10개의 데이터를 10번 검색한다는 것을 알게 됩니다. 클러스터형 인덱스인 경우에도 여전히 공동 인덱스를 사용합니다. 🎜🎜2 Covering index🎜🎜 Covering index는 인덱스가 아니라 인덱스를 기반으로 쿼리하는 방법일 뿐입니다. 즉, 🎜rrreee🎜와 같이 공동 인덱스의 일부 필드 값만 필요한 경우입니다. , 결합 인덱스 트리의 인덱스만 스캔하면 되며, 다른 필드를 찾기 위해 테이블로 돌아갈 필요가 없습니다. *를 선택
하는 대신 SQL에 필요한 필드만 지정하는 것이 가장 좋습니다. limit
및 where
를 사용하여 테이블 반환 수를 최대한 제한하고 작은 필터링을 수행해야 합니다. 조인트 인덱스에서 데이터 수를 가져온 다음 테이블로 반환하므로 성능이 더 좋습니다. 🎜위 내용은 MySQL 테이블 반환의 성능 소비는 얼마나 됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!