MySQL之索引

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL之索引

索引查找算法BTREE

BTREE查找算法演变B-TREE :普通 BTREE,平衡多路查找树(B-Tree)B+TREE :叶子节点双向指针B++TREE(B*TREE):枝节点的双向指针


普通B-TREE

增强版B+TREE(B*TREE)

640.png

总结:从上图看出,在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。从上图中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。而BTree,这个是以B+Tree为基础,在非叶子结点(枝节点)上增加了链表指针,BTree的空间利用率更高。

MySQL中如何使用BTREE

1 聚簇索引

聚簇索引也叫集群索引,聚集索引。它不是一种单独的索引类型,而是一种数据存储方式。Innodb的聚簇索引实际上在同一个结构中保存了B*Tree索引和数据行。当表有聚簇索引时,数据行实际上存储在索引的叶子节点中。聚簇的意思是表示数据行和相邻的键值紧凑地存储在一起。一个表只能有一个聚簇索引。也就是按照每张表的主键构成一棵B+树,叶子节点中存放整张表的行记录数据,也将聚集索引的叶子节点成为数据页,每个数据页之间通过一个双向链表来进行链接。数据页存放的是每行的所有记录,非数据页存放的是键值和指向数据页的偏移量。它可以在叶子节点直接找到数据,且对于主键的排序查找和范围查找速度非常快,因为聚集索引是逻辑上连续的。比如查询后10条数据,由于B+树索引是双向链表,可以很快找到随后一个数据页,然后取出最后的10条数据。

①前提条件

1.如果表中设置了主键(例如ID列),自动根据ID列生成索引树。
2.如果没有设置主键,自动选择第一个唯一键的列作为聚簇索引
3.如果没有唯一键,自动生成隐藏的聚簇索引。
4.在建表时,推荐创建主键为数字自增列。

②功能

1.录入数据时,按照聚簇索引组织存储数据,在磁盘上有序存储数据行。
2.加速查询(基于ID作为条件的判断查询)。

③聚簇索引的B*Tree构建过程

a. 叶子节点:存储数据行时就是有序的,直接将数据行的page作为叶子节点(相邻的叶子结点,有双向指针)
b. 枝节点  :提取叶子节点ID的范围+指针,构建枝节点(相邻枝节点,有双向指针)
c. 根节点  :提取枝节点的ID的范围+指针,构建根节

640.png

2 辅助索引

辅助索引需要人为创建辅助索引,将经常作为查询条件的列创建辅助索引,起到加速查询的效果。也称非聚集索引,按照每张表创建的索引列创建一棵B+树,叶子节点并不包含行记录的全部数据。叶子节点包含键值 和 书签,书签用来告诉InnoDB存储引擎在哪可以找到与索引对应的行数据,每张表可以有多个辅助索引。如果某个查询是通过辅助索引查找数据的,则查找过程为:先遍历辅助索引并找到叶节点找到指针获取主键索引的主键,然后通过主键索引找到对应的页从而找到一个完整的行记录。注:没执行一次查询就是一次IO,比如 辅助索引树高度为3,聚集索引树高度为2,则通过辅助索引查询数据时就要进行3+2次逻辑IO最终得到一个数据页。

辅助索引的B*Tree 构建过程

a. 叶子节点:提取主键(ID)+辅助索引列,按照辅助索引列进行从小到大排序后,生成叶子节点。(多个辅助索引列,以最左边的列为标准。相邻的叶子结点,有双向指针。)
b. 枝节点  :提取叶子节点辅助索引列的范围+指针,构建枝节点(相邻枝节点,有双向指针)
c. 根节点  :提取枝节点的辅助索引列的范围+指针,构建根节点

辅助索引查询过程:

# 按照辅助索引列,作为查询条件时。
1. 查找辅助索引树,得到ID值
2. 拿着ID值回表(聚簇索引)查询

①单列索引

只拿一个非主键列来创建索引,如下:

# 单列辅助索引 
select * from test.t100w where k2='780P'
# 优化方式: 
alter table 表名 add index 索引名(列名);
mysql> alter table t100w add index idx_k2(k2);

②联合索引

# 使用多个非主键列创建辅助索引
mysql> alter table t100w add index idx_k1_num(k1,num);

③前缀索引

列值长度越长,数据量大的话,会影响到索引高度,需要使用前缀索引,也就是截取列值的前缀生成新的索引以提高效率。

# 判断前缀长度多少合适:截取字符串之后得到的总记录数越接近截取之前的越好,说明前缀的唯一性高!
select count(distinct(left(name,5)))  from city ;
select count(distinct name)  from city ;
# 创建前缀索引
mysql> alter table city add index idx_n(name(5));
# 删除索引
mysql> alter table city drop index idx_n;

关于索引的相关问题

1 回表问题

# 关于辅助索引回表是什么?回表会带来什么问题?怎么减少回表?
a. 回表:按照辅助索引列作为查询条件时,先查找辅助索引树,再到聚簇索引树查找数据行的过程。
b. 影响:IO量多、IO次数多、随机IO会增多
c. 减少回表:
  1. 辅助索引能够完全覆盖查询结果,可以使用联合索引。
  2. 尽量让查询条件精细化,尽量使用唯一值多的列作为查询条件
  3. 优化器:MRR(Multi-Range-Read), 锦上添花的功能。
         mysql> select @@optimizer_switch;
         mysql> set global optimizer_switch='mrr=on';
功能:
(1)辅助索引查找后得到ID值,进行自动排序
(2)一次性回表,很有可能受到B+TREE中的双向指针的优化查找。

2 索引树高度的影响因素

a. 高度越低越好
b. 数据行越多,高度越高。
   1. 分区表。一个实例里管理。基本不再使用了!
   2. 按照数据特点,进行归档表。
   3. 分布式架构。针对海量数据、高并发业务主流方案。
   4. 在设计方面,满足三大范式。
c. 主键规划:长度过长。
   1. 主键,尽量使用自增数字列。
d. 列值长度越长,数据量大的话,会影响到高度。
   1. 使用前缀索引
   比如列值长100字符,那么只取前10个字符,构建索引树。
e. 数据类型的选择。
   选择合适的、简短的数据类性。
   例如:
   1. 存储人的年龄  ,使用 tinyint 和 char(3)哪个好一些
   2. 存储人名,char(20)和varchar(20)的选择哪一个好。
      a. 站在数据插入性能角度思考,应该选:char    
      b. 从节省空间角度思考,应该选:varchar
      c. 从索引树高度的角度思考,应该选:varchar
结论:建议使用varchar类型存储变长列值

创建索引

查询表索引

mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   | MUL |         |                |
| CountryCode | char(3)  | NO   | UK |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
PK     --> 主键(聚簇索引)     
MUL    --> 辅助索引   
UK     --> 唯一索引 
mysql> show index from city;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| city  |          0 | PRIMARY     |            1 | ID          | A         |        4188 |     NULL | NULL   |      | BTREE      |         |               |
| city  |          1 | CountryCode |            1 | CountryCode | A         |         232 |     NULL | NULL   |      | BTREE      |         |               |
| city  |          1 | idx_name    |            1 | Name        | A         |        3554 |        5 | NULL   |      | BTREE      |         |               |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
# Cardinality值越大,索引优先级越高。

创建索引

# 单列辅助索引 
select * from test.t100w where k2='780P'; # 该表没有索引,大量数据查询耗时极大,需要优化!
优化方式:
语法:alter table 表名 add index 索引名(列名);  
alter table t100w add index idx_k2(k2);
# 联合索引创建 
mysql> alter table t100w add index idx_k1_num(k1,num);
# 前缀索引创建
# 判断前缀长度多少合适:
select count(distinct(left(name,5)))  from city ;
select count(distinct name)  from city ;
# 创建前缀索引
mysql> alter table city add index idx_n(name(5));
# 删除索引
alter table city drop index idx_n;

执行计划获取和分析

1 执行计划工具

# 获取语句的执行计划工具
  explain 
  des
# 使用方法 :
mysql> desc select * from city where countrycode='CHN';
mysql> explain  select * from city where countrycode='CHN';
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  363 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+

2 执行计划信息

table         :此次查询访问的表
type          :索引查询的类型(ALL、index、range、ref、eq_ref、const(system)、NULL)
possible_keys :可能会应用的索引
key           : 最终选择的索引
key_len       :索引覆盖长度,主要是用来判断联合索引应用长度。
rows          :需要扫描的行数
Extra         :额外信息

3 Type信息详解

代价从高到低!

  • ALL
# 没有使用到索引
a. 查询条件没建立索引
# district并没有被创建成辅助索引
mysql> desc select * from city where district='shandong';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | city  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 4188 |    10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
b. 有索引不走
# 这三种查询不走索引
mysql> desc select * from city where countrycode!='CHN';
mysql> desc select * from city where countrycode not in ('CHN','USA');
mysql> desc select * from city where countrycode like '%CH%';

index

# 全索引扫描 
mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   | MUL |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> desc select countrycode from city;
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | city  | NULL       | index | NULL          | CountryCode | 3       | NULL | 4188 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
# 由于country是辅助索引,这里查询会遍历扫描索引,效率也是一种问题。

range

从这里开始,我们可以接受这些类型的索引查询,但是无法容忍上述两种!

# 索引范围扫描
# 会受到:B+TREE额外优化,叶子节点双向指针
# >、<、>=、<=、in、or、between and、like
mysql> desc select * from city where id<10;
mysql> desc select * from city where countrycode like 'CH%';
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | city  | NULL       | range | CountryCode   | CountryCode | 3       | NULL |  397 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
# 这种情况下,主键索引性能还可以,如果查询条件是辅助索引,就会牵扯到回表次数问题而导致性能较低。
# 以下两种查询,大几率受不到叶子节点双向指针优化。
# 他会遍历两个值之间的数据,而这种遍历是没有必要的!
mysql> desc select * from city where countrycode in ('CHN','USA');
mysql> desc select * from city where countrycode='CHN' or countrycode='USA';
# 建议:如果查询列重复值少的话,我们建议改写为 union all (2-3个,如果超过50%,那就没什么卵用了!)
desc 
select * from city where countrycode='CHN'
union all
select * from city where countrycode='USA';
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | PRIMARY     | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  363 |   100.00 | NULL  |
|  2 | UNION       | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  274 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)

ref

# 辅助索引等值查询
desc select * from city where countrycode='CHN';
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  363 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
# 等值查询的代价比range就要低很多了。

eq_ref

# 多表连接查询中,非驱动表的连接条件是主键或唯一键时。
mysql> desc select city.name,country.name 
from city 
left join country 
on city.countrycode=country.code where city.population<100;
# 在非驱动表country中code是主键,在多表连接中如果显示未eq_ref,那就是最佳的优化实践,也是性能最好的一种场景。这也是多表连接中非驱动表的优化方向。驱动表后续会介绍。
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+
| id | select_type | table   | partitions | type   | possible_keys | key     | key_len | ref                    | rows | filtered | Extra       |
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+
|  1 | SIMPLE      | city    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL                   | 4188 |    33.33 | Using where |
|  1 | SIMPLE      | country | NULL       | eq_ref | PRIMARY       | PRIMARY | 3       | world.city.CountryCode |    1 |   100.00 | NULL        |
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
# 这个时候我们把population条件创建为一个辅助索引,驱动表走的索引就是range。这也是最好的一种优化了,没有别的方式比这个性能更好了,知足吧!
mysql> alter table city add index idx_p(population);
mysql> desc select city.name,country.name  from city  left join country  on city.countrycode=country.code where city.population<100;
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-----------------------+
| id | select_type | table   | partitions | type   | possible_keys | key     | key_len | ref                    | rows | filtered | Extra                 |
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-----------------------+
|  1 | SIMPLE      | city    | NULL       | range  | idx_p         | idx_p   | 4       | NULL                   |    1 |   100.00 | Using index condition |
|  1 | SIMPLE      | country | NULL       | eq_ref | PRIMARY       | PRIMARY | 3       | world.city.CountryCode |    1 |   100.00 | NULL                  |
+----+-------------+---------+------------+--------+---------------+---------+---------+------------------------+------+----------+-----------------------+
2 rows in set, 1 warning (0.00 sec)

const(system)

# 主键或唯一键等值查询
# 性能最好,只需回表一次,这是一种奢望!
mysql> desc select * from city where id=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | city  | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

NULL

# 查不到数据的时候性能最好!那我要你有何用!!!不用管了!!!
mysql> desc select * from city where id=1000000000000000;

总结

通常最常见的执行计划类型是:range、ref、eq_ref。
如果出现index或者all的情况,那就可能涉及到改写sql查询语句,或者得找业务沟通查询条件了。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
存储 自然语言处理 关系型数据库
MySQL高级篇——索引的创建与设计原则
索引的分类与使用、MySQL8.0索引新特性、适合创建索引的情况、不适合创建索引的情况
MySQL高级篇——索引的创建与设计原则
|
19天前
|
存储 SQL 关系型数据库
MySQL高级篇——索引失效的11种情况
索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4
MySQL高级篇——索引失效的11种情况
|
28天前
|
存储 关系型数据库 MySQL
MySQL基础:索引
MySQL中的索引是一种数据结构,能大幅提升数据库查询效率和减少I/O成本,类似于书的目录帮助快速定位内容。其优势包括提高检索效率和降低排序成本,但会占用空间并影响更新表的效率。鉴于查询远多于更新,索引仍被推荐使用。索引分为多种类型,如B+树和哈希索引,其中B+树因其较低的高度和稳定的查询开销成为常用选择。创建和删除索引需谨慎,以免影响性能。
42 4
MySQL基础:索引
|
19天前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
165 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
19天前
|
存储 缓存 关系型数据库
MySQL高级篇——存储引擎和索引
MyISAM:不支持外键和事务,表锁不适合高并发,只缓存索引,内存要求低,查询快MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务、行级锁、外键,有一个毫无疑问的缺陷就是崩溃后无法安全恢复。5.5之前默认的存储引擎优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用针对数据统计有额外的常数存储。故而 count(*) 的查询效率很高表名.frm 存储表结构;表名.MYD 存储数据 (MYData);
MySQL高级篇——存储引擎和索引
|
19天前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
3天前
|
存储 关系型数据库 MySQL
MySQL索引失效及避免策略:优化查询性能的关键
MySQL索引失效及避免策略:优化查询性能的关键
15 3
|
8天前
|
关系型数据库 MySQL 数据库
MySQL删除全局唯一索引unique
这篇文章介绍了如何在MySQL数据库中删除全局唯一的索引(unique index),包括查看索引、删除索引的方法和确认删除后的状态。
30 9
|
3天前
|
存储 SQL 关系型数据库
MySQL 的索引是怎么组织的?
MySQL 的索引是怎么组织的?
10 1
|
3天前
|
存储 关系型数据库 MySQL
MySQL索引的概念与好处
本文介绍了MySQL存储引擎及其索引类型,重点对比了MyISAM与InnoDB引擎的不同之处。文中详细解释了InnoDB引擎的自适应Hash索引及聚簇索引的特点,并阐述了索引的重要性及使用原因,包括提升数据检索速度、实现数据唯一性等。最后,文章还讨论了主键索引的选择与页分裂问题,并提供了使用自增字段作为主键的建议。
MySQL索引的概念与好处
下一篇
无影云桌面