解密 MySQL:索引—优化数据库性能的关键(一)

238 天前
 th3ee9ine

摘要:索引是关系型数据库中的关键性工具,用于加速数据检索和查询操作。通过了解索引的基本原理和工作机制,我们能够更好地优化和管理数据库,确保应用程序的高效运行。


一、索引基础

在我们深入讨论 MySQL 索引的不同类型和优化策略之前,让我们首先了解一下索引的基础知识。

1 、什么是索引?

索引是数据库中的一种数据结构,它类似于书籍的目录。它帮助数据库管理系统快速查找和定位数据,而不必扫描整个表。

索引通过创建索引键( index key )与实际数据行的对应关系,使得查询操作更加高效。

索引通常基于表的一个或多个列。

2 、索引的作用

索引的主要作用是加速数据检索操作,特别是在大型数据库表中。 它们可以大大减少查询响应时间,提高数据库的性能。

没有索引的情况下,数据库引擎需要逐行扫描整个表以找到匹配条件的数据,而索引允许它快速定位所需的行。

3 、索引与查询性能的关系

索引与数据库查询性能密切相关。一个优化良好的索引可以使查询速度大幅提升,而一个不合理的索引设计可能导致性能下降。

查询性能的提高主要体现在以下方面:

4 、索引的数据结构

通常使用一种被称为 B 树或 B+树的数据结构来实现索引。这种树结构允许数据库引擎快速地定位索引键的值,并找到对应的数据行。

B 树和 B+树之所以被广泛用于索引,是因为它们在插入、删除和查找操作方面都表现出色,并且可以有效地处理大量数据。它们之间的主要区别包括以下几个方面:

5 、MyISAM 引擎与 InnoDB 引擎的索引结构的差别

MyISAM 引擎

MyISAM 引擎是使用 B+Tree 作为索引结构,叶子节点的 data 域存放的是数据记录的地址。

MyISAM 索引文件和数据文件是分离的(非聚簇索引),MyISAM 的索引文件仅仅保存数据记录的地址。MyISAM 中首先搜索索引,如果指定的 Key 存在,则取出其 data 域的值,然后以 data 域的值为地址,读取相应数据记录。

物理文件结构为:

InnoDB 引擎

InnoDB 引擎也是使用 B+Tree 作为索引结构,但是 InnoDB 的数据文件本身就是索引文件,叶子节点 data 域保存了完整的数据记录。

索引的 key 是数据表的主键,因此 InnoDB 表数据文件本身就是主键索引(聚簇索引)。InnoDB 的辅助索引的 data 域存储相应记录主键的值而不是地址。这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引(回表)。 所以我们在使用索引的时候,应注意以下两点:

物理文件结构为:

二、MySQL 索引类型

MySQL 索引可以按照多种不同的分类方式进行分组。以下是根据不同类别对 MySQL 索引进行的一些常见分类:

按数据结构分类:

按物理存储分类:

按字段特性分类:

按字段个数分类:

三、索引的创建与使用

正确创建和使用索引可以显著提高查询性能,但错误的使用可能导致性能下降或不必要的存储开销。在本节中,我们将讨论如何创建和使用索引。

注:下面的内容如果没有特别说明,都是默认使用 Innodb 存储引擎。

1 、创建索引

创建索引的语法如下:

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
    [index_type]
    ON tbl_name (key_part,...)
    [index_option]
    [algorithm_option | lock_option] ...

key_part: {col_name [(length)] | (expr)} [ASC | DESC]

    index_option: {
    KEY_BLOCK_SIZE [=] value
    | index_type
    | WITH PARSER parser_name
    | COMMENT 'string'
    | {VISIBLE | INVISIBLE}
    | ENGINE_ATTRIBUTE [=] 'string'
    | SECONDARY_ENGINE_ATTRIBUTE [=] 'string'
    }

    index_type:
    USING {BTREE | HASH}

    algorithm_option:
    ALGORITHM [=] {DEFAULT | INPLACE | COPY}

    lock_option:
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}

主键索引(PRIMARY KEY)

ALTER TABLE `table_name` ADD PRIMARY KEY (`column`)

唯一索引(UNIQUE)

ALTER TABLE `table_name` ADD UNIQUE (`column`)

普通索引(INDEX)

单列索引

ALTER TABLE `table_name` ADD INDEX index_name(`column`)

复合索引

ALTER TABLE `table_name` ADD INDEX index_name(`column1`, `column2`, `column3`)

前缀索引

# 语法
ALTER TABLE `table_name` ADD INDEX index_name(`column1`[length],  `column2`[length], ...)
# 例子
ALTER TABLE `user_info` ADD INDEX idx_id_name(`id`(10),  `name`(3))

全文索引(FULLTEXT)

ALTER TABLE `table_name` ADD FULLTEXT (`column`);

空间索引(SPATIAL INDEX)

# 语法
CREATE SPATIAL INDEX `index_name` ON `table_name`(`column`);
# 例子
CREATE SPATIAL INDEX spatial_index ON city(location);

2 、修改、删除索引

MySQL 中没有真正意义上的修改索引,只有先删除后再创建新的索引才可以达到修改的目的。

具体原因如下:

# 语法:
DROP INDEX 索引名称 ON 表名;
# 例子:
DROP INDEX idx_id_name ON `user_info`;

# 修改:
DROP INDEX idx_id_name ON `user_info`;
ALTER TABLE `user_info` ADD INDEX idx_name ( `name` );

3 、查询索引

# 语法:SHOW INDEX FROM 表名;
# 例如:
SHOW INDEX FROM `user_info`;

4 、创建与使用索引的注意事项

四、结尾

通过上面的内容,我们对 MySQL 索引的基础知识有了一个大致的了解,知道了如何创建与使用索引了,但是这些内容还不足以让我们用好索引,下篇文章,我们将继续深入了解索引的其他知识点,内容包括:最左匹配原则、覆盖索引、前缀索引、索引下推、回表、MRR(Multi-Range Read)、ICP(Index Condition Pushdown)等等。。。

参考资料

原文链接:解密 MySQL:索引—优化数据库性能的关键(一)

微信公众号:啊杰在拱趴

求关注!!!!

1198 次点击
所在节点    MySQL
3 条回复
th3ee9ine
238 天前
新人公众号,求关注!!!
微信公众号:啊杰在拱趴
pursuit
228 天前
支持。已关注~
th3ee9ine
228 天前
@pursuit 感谢哈哈哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/974091

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX