이 기사에서는 MySQL 인덱스의 13가지 지식 포인트를 소개합니다. 면접에 많은 도움이 될 것입니다. 이제 공유하겠습니다.
솔직히 데이터베이스 인덱싱에 관련된 지식은 정말 복잡해요. 원래는 이 부분을 잘 살펴보고 자세히 이야기하는 글을 쓰고 싶었는데, 나중에 보니 인덱싱에 대한 지식이 부족하더군요. 너무 어렵고 너무 깊습니다. 종합적이고 자세하게 이야기하는 것은 정말 어렵기 때문에 결국 제가 배우고 생각한 내용을 다음과 같은 질문으로 전환해 보았습니다.
데이터베이스 인덱스는 데이터베이스 시스템에서 중요한 개념입니다. 인덱스는 데이터베이스 쿼리의 효율성을 높이기 위해 사용되는 데이터 구조입니다. 책의 목차를 통해 목차에서 해당 장의 내용을 빠르게 찾을 수 있습니다. 마찬가지로 데이터베이스 색인을 통해 데이터 테이블에서 해당 레코드를 빠르게 찾을 수 있습니다. key
,是一种用于提升数据库查询效率的数据结构,我们可以把索引理解成一本书的目录,通过目录我们可以快速找到对应章节的内容,同样的,通过数据库索引,我们可以快速找到数据表中对应的记录。
总而言之,索引就像给数据表建了一个目录一样。
1 . 使用索引大大减少了存储引擎需要扫描的数据量,如果没有使用索引的话,每查询一行数据都要对数据表进行扫描,这样的话会非常慢。
2 . 由于索引已经排好序的,所以对数据表进行 ORDER BY
和 GROUP BY
等操作时,可以很快得到结果。
3 . 索引可以将随机的 I/O
转为顺序的 I/O
,避免高昂的磁盘 IO
成本,提升查询效率。
(免费学习视频教程推荐:mysql视频教程)
MySQL
的索引是在存储引擎这一层实现的,因此每一种存储引擎都有不同的实现方式,对同一种索引的处理方式也完成不同。
如果使用以 %
开头的 LIKE
语句进行模糊匹配,则无法使用索引,如:
SELECT * FROM users WHERE name LIKE '%小张%'; SELECT * FROM users WHERE name LIKE '%小张';
不过以 %
为结尾则可以使用索引,如:
SELECT * FROM users WHERE name LIKE '张%';
OR
语句前后没有同时使用索引,比如下面的语句, 字段id
有索引,而 字段name
没有创建索引,那么下面的语句只能全表扫描,无法用到索引:
SELECT * FROM users id = 10 or name='test'复制代码
问题5:MySQL索引底层使用什么数据结构?
在 MySQL
中,大部分情况下,索引都是使用 B-Tree
作为底层数据结构, B-Tree
只是一种泛称,实际上不同的存储引擎使用 B-Tree
时,有不同的变种,比如 InnoDB
使用的是 B+Tree
。
另外也有一些特殊的索引结构,比如哈希索引,哈希索引底层则使用的是哈希表,在 MySQL
中,只有 Memory
存储引擎支持哈希索引。
1 . 对于用于存储归档历史数据的且很少用于查询的数据表,不建议创建索引。
2 . 数据量比较小的数据表,而且未来数据也不会有太大增长的数据,不应该建索引,比如用于保存配置的数据表。
3 . 修改频繁,且修改性能远大于查询性能时,不应该再创建索引。
回表是对Innodb存储引擎而言的,在 InnoDB
存储引擎中,主键索引的叶子节点存储的记录的数据,而普通索引的叶子节点存储的主键索引的地点。
当我们通过主键查询时,只需要搜索主键索引的搜索树,直接可以得到记录的数据。
当我们通过普通索引进行查询时,通过搜索普通索引的搜索树得到主键的地址之后,还要再使用该主键对主键搜索树进行搜索,这个过程称为回表。
聚簇索引:聚簇索引的顺序就是数据的物理存储顺序,并且索引与数据放在一块,通过索引可以直接获取数据,一个数据表中仅有一个聚簇索引。
非聚簇索引:索引顺序与数据物理排列顺序无关,索引文件与数据是分开存放。
设置为主键索引的字段不允许为 NULL
ORDER BY
, GROUP BY
등의 작업을 수행하면 결과를 빠르게 얻을 수 있습니다. 🎜🎜3. 인덱스는 무작위 I/O
를 순차적 I/O
로 변환하여 높은 디스크 IO
비용을 방지하고 쿼리 효율성을 향상시킬 수 있습니다. 🎜🎜질문 3: MySQL 인덱스는 어떤 모듈에 구현되어 있나요? 🎜🎜 (추천 무료 학습 동영상 튜토리얼: mysql 동영상 튜토리얼) 🎜🎜MySQL
의 인덱스는 스토리지 엔진 레벨에서 구현되기 때문에 스토리지 엔진마다 구현 방식이 다르며, 동일한 인덱스라도 다르게 처리됩니다. 🎜🎜질문 4: 인덱스 설정 후 왜 작동하지 않나요? 🎜🎜퍼지 매칭을 위해 %
로 시작하는 LIKE
문을 사용하는 경우 다음과 같이 인덱스를 사용할 수 없습니다. 🎜CREATE TABLE test( a INT NOT NOT, b INT NOT NOT, KEY(a,b) );🎜 그러나
% 다음과 같은 인덱스를 사용할 수 있습니다. 🎜<pre class="brush:php;toolbar:false;">SELECT * FROM test WHERE a=1 AND b=1;</pre>🎜 <code>OR
명령문 앞뒤에 인덱스가 사용되지 않습니다. 예를 들어 다음 문에서는 field id
입니다. 인덱스가 있고 필드 이름
code> 인덱스가 생성되지 않은 경우 다음 문은 전체 테이블만 스캔할 수 있으며 인덱스를 사용할 수 없습니다. 🎜SELECT * FROM test WHERE a=1;🎜 질문 5: 데이터 구조란 무엇입니까? MySQL 인덱스의 맨 아래에 사용됩니까? 🎜🎜
MySQL
에서 대부분의 경우 인덱스는 B-Tree
를 기본 데이터 구조로 사용하고, B-Tree
는 단지 실제로 B-Tree
를 사용할 때 스토리지 엔진마다 변형이 다릅니다. 예를 들어 InnoDB
는 B+Tree
를 사용합니다. 🎜🎜해시 인덱스와 같은 일부 특수 인덱스 구조도 있습니다. 해시 인덱스의 최하위 계층은 해시 테이블을 사용합니다. MySQL
에서는 메모리
스토리지 엔진만 지원합니다. 해시 인덱스. 🎜🎜질문 6: 어떤 상황에서 데이터 테이블이 인덱스 생성에 적합하지 않습니까? 🎜🎜1. 보관된 기록 데이터를 저장하는 데 사용되며 쿼리에 거의 사용되지 않는 데이터 테이블에 대해서는 인덱스를 생성하지 않는 것이 좋습니다. 🎜🎜2. 상대적으로 데이터 양이 적은 데이터 테이블과 향후 크게 증가하지 않는 데이터는 구성을 저장하는 데 사용되는 데이터 테이블과 같은 인덱스를 구축해서는 안 됩니다. 🎜🎜3. 수정이 자주 발생하고 수정 성능이 쿼리 성능보다 훨씬 높을 경우 더 이상 인덱스를 생성하면 안 됩니다. 🎜🎜질문 7: 반품 양식이란 무엇인가요? 🎜🎜테이블 반환은 Innodb 스토리지 엔진용입니다. InnoDB
스토리지 엔진에서 기본 키 인덱스의 리프 노드는 기록된 데이터를 저장하고 일반 인덱스의 리프 노드는 데이터의 위치를 저장합니다. 기본 키 인덱스. 🎜🎜기본키로 쿼리할 경우 기본키 인덱스의 검색트리만 검색하면 기록된 데이터를 바로 얻을 수 있습니다. 🎜🎜일반 인덱스를 통해 쿼리할 때 일반 인덱스의 검색 트리를 검색하여 기본 키의 주소를 얻은 후 기본 키 검색 트리를 검색하려면 기본 키를 사용해야 합니다. 이 프로세스를 테이블이라고 합니다. 반품. 🎜🎜질문 8: 클러스터형 인덱스와 비클러스터형 인덱스의 차이점은 무엇인가요? 🎜🎜클러스터형 인덱스: 클러스터형 인덱스의 순서는 데이터가 물리적으로 저장되는 순서로, 인덱스와 데이터가 함께 배치되는 방식으로, 데이터 테이블에는 클러스터형 인덱스가 하나만 존재합니다. . 🎜🎜비클러스터형 인덱스: 인덱스 순서는 데이터의 물리적 배열 순서와 무관하며, 인덱스 파일과 데이터가 별도로 저장됩니다. 🎜🎜질문 9: MySQL 기본 키 인덱스, 고유 인덱스 및 일반 인덱스의 차이점은 무엇입니까? 🎜🎜기본 키 인덱스로 설정된 필드는 NULL
이 허용되지 않으며, 데이터 테이블은 기본 키 인덱스를 하나만 가질 수 있습니다. 🎜🎜고유 인덱스로 설정된 필드의 경우 해당 필드 값이 중요할 수 없습니다. 🎜普通索引可以包含重复的值,也可以为 NULL
。
索引作为一个数据表的目录,本身的存储就需要消耗很多的磁盘和内存存储空间。
并助在写入数据表数据时,每次都需要更新索引,所以索引越多,写入就越慢。
尤其是糟糕的索引,建得越多对数据库的性能影响越大。
MyISAM
存储引擎是非聚族索引,索引与数据是分开存储的,索引文件中记录了数据的指针
而 InnoDB
存储引擎是聚族索引,即索引跟数据是放在一块的, InnoDB
一般将主键与数据放在一块,如果没有主键,则将 unique key
作为主键,如果没有 unique key
,则自动创建一个 rowid
作为主键,其他二级索引叶子指针存储的是主键的位置。
MySQL
数据库不单可以为单个数据列创建索引,也可以为多个数据列创建一个联合索引,比如:
CREATE TABLE test( a INT NOT NOT, b INT NOT NOT, KEY(a,b) );
当我们使用下面的查询语句时,由于 WHERE
语句中查询的条件就是联合索引,所以可以很快查询到数据。
SELECT * FROM test WHERE a=1 AND b=1;
同样,下面的语句也会利用上面创建的联合索引,这是因为 MySQL
会按照索引创建的顺序进行排序,然后根据查询条件从索引最左边开始检测查询条件是否满足该索引,由于字段 a
在最左边,所以满足索引。
SELECT * FROM test WHERE a=1;
而使用 字段b
进行查询时,则为满足,因为从最左边匹配到的是 字段a
,所以 MySQL
判断为不满足索引条件。
SELECT * FROM test WHERE b=1;
从上面例子可以很好地了解索引的最左前缀原则,同时也说明了索引顺序的重要性。
如果一个索引中包含查询所要的字段时,此时不需要再回表查询,我们就称该索引为覆盖索引。
比如下面的查询中,字段id是主键索引,所以可以直接返回索引的值,显著提升了查询的性能。
SELECT id FROM users WHERE id BETWEEN 10 AND 20;
当然,上面列出的只是索引的一小部分知识点,有什么回答不对的地方,欢迎指出。
위 내용은 마스터해야 할 13가지 MySQL 인덱스 지식 포인트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!