最详细的mysql索引解析(文末附赠思维导图)(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
全局流量管理 GTM,标准版 1个月
简介: 最详细的mysql索引解析(文末附赠思维导图)(一)

一、索引的概念


1.1 数据库索引

索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于c语言的链表通过指针指向数据记录的内存地址)

使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据,因此能加快数据库的查询速度。

索引就好比是一本书的目录,可以根据目录中的页码快速找到所需的内容。

索引是表中一列或者若干列值排序的方法。

建立索引的目的是加快对表中记录的查找或排序。

select * from student where id=5;
#要找到id为5的记录,需要全表扫描,如果记录(行)很多,会查询的很慢

1.2 索引的作用及副作用

1.2.1 索引的作用

设置了合适的索引之后,数据库利用各种快速定位技术,能够大大加快查询速度,这是创建索引的最主要的原因。

当表很大或查询涉及到多个表时,使用索引可以成千上万倍地提高查询速度。

可以降低数据库的Io成本,并且索引还可以降低数据库的排序成本。

通过创建唯一性索引,可以保证数据表中每一行数据的唯一性。

可以加快表与表之间的连接。

在使用分组和排序时,可大大减少分组和排序的时间。

建立索引在搜索和恢复数据库中的数据时能显著提高性能

#假设对id字段做了索引
select * from student where id=5;
#通过索引表找到这个数据所在的物理地址,然后通过物理地址对应的数据
#但是只对id做索引,找name字段还是会全表扫描


1.2.2 索引的副作用

索引需要占用额外的磁盘空间。

对于MyISAM引擎而言,索引文件和数据文件是分离的,索引文件用于保存数据记录的地址。而InnoDB 引擎的表数据文件本身就是索引文件。

在插入和修改数据时要花费更多的时间,因为索引也要随之变动。


1.3 创建索引的原则依据

索引虽可以提升数据库查询的速度,但并不是任何情况下都适合创建索引。因为索引本身会消耗系统资源,在有索引的情况下,数据库会先进行索引查询,然后定位到具体的数据行,如果索引使用不当,反而会增加数据库的负担。


表的主键、外键必须有索引。因为主键具有唯一性,外键关联的是主表的主键,查询时可以快速定位。

记录数超过300行的表应该有索引。如果没有索引,每次查询都需要把表遍历一遍,会严重影响数据库的性能。

经常与其他表进行连接的表,在连接字段上应该建立索引。

唯一性太差的字段不适合建立索引。·更新太频繁地字段不适合创建索引。

经常出现在where子句中的字段,特别是大表的字段,应该建立索引。

在经常进行GROUP BY、ORDERBY的字段上建立索引;

索引应该建在选择性高的字段上

索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引。


二、索引的分类和创建


create table member (id int(10),name varchar(10),cardid int(18),phone int(11),address varchar(50),remark text);
 mysql> desc member;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | YES  |     | NULL    |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  |     | NULL    |       |
| phone   | int(11)     | YES  |     | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)

2.1 普通索引

基本的索引类型,没有唯一性之类的限制


2.1.1 直接创建索引

CREATE INDEX 索引名 ON 表名 (列名[(length)]);
create index name_index on member(name);
mysql> show create table member \G;
*************************** 1. row ***************************
       Table: member
Create Table: CREATE TABLE `member` (
  `id` int(10) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  `cardid` int(18) DEFAULT NULL,
  `phone` int(11) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `remark` text,
  KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


(列名(length)):length是可选项,下同。如果忽略 length 的值,则使用整个列的值作为索引。如果指定使用列前的 length 个字符来创建索引,这样有利于减小索引文件的大小。

索引名建议以“_index”结尾。



2.1.2 修改表结构方式创建索引

ALTER TABLE 表名 ADD INDEX 索引名 (列名); 
 mysql> alter table member add index phone_index(phone);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table member \G;
*************************** 1. row ***************************
       Table: member
Create Table: CREATE TABLE `member` (
  `id` int(10) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  `cardid` int(18) DEFAULT NULL,
  `phone` int(11) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `remark` text,
  KEY `name_index` (`name`),
  KEY `phone_index` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


2.1.3 创建表的时候指定索引

CREATE TABLE 表名 ( 字段1 数据类型,字段2 数据类型[,...],INDEX 索引名 (列名));
create table member1 (id int(10),name varchar(10),cardid int(18),phone int(11),address varchar(50),remark text,index name_index(name));


2.2 唯一索引

与普通索引类似,但区别是唯一索引列的每个值都唯一。唯一索引允许有空值(注意和主键不同)。如果是用组合索引创建,则列值的组合必须唯一。添加唯一键将自动创建唯一索引。


2.2.1 直接创建唯一索引

CREATE UNIQUE INDEX 索引名 ON 表名(列名);
mysql> create unique index cardid_index on member(cardid);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql>  desc member;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | YES  |     | NULL    |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  | UNI | NULL    |       |
| phone   | int(11)     | YES  |     | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)


2.2.2 修改表方式创建唯一索引

ALTER TABLE 表名 ADD UNIQUE 索引名 (列名); 
 mysql> alter table member add unique phone_index(phone);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql>  desc member;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | YES  |     | NULL    |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  | UNI | NULL    |       |
| phone   | int(11)     | YES  | UNI | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)


2.2.3 创建表的时候指定唯一索引

CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型[,...],UNIQUE 索引名 (列名));
 mysql> create table member2 (id int(10),name varchar(10),cardid int(18),phone int(11),address varchar(50),remark text,unique id_index(id));
 mysql>  desc member2;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | YES  | UNI | NULL    |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  |     | NULL    |       |
| phone   | int(11)     | YES  |     | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)


2.3 主键索引

是一种特殊的唯一索引,必须指定为“PRIMARYKEY"。一个表只能有一个主键,不允许有空值。添加主键将自动创建主键索引。


2.3.1 创建表的时候指定主键索引

CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型[,...], PRIMARY KEY  (列名));
mysql> create table member3 (id int(10),name varchar(10),cardid int(18),phone int(11),address varchar(50),remark text,primary key(id));
Query OK, 0 rows affected (0.00 sec)
mysql> desc member3;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | NO   | PRI | 0       |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  |     | NULL    |       |
| phone   | int(11)     | YES  |     | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)


2.3.2 修改表方式创建主键索引

ALTER TABLE 表名 ADD PRIMARY key (列名); 
mysql> alter table member add primary key(id);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> desc member;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(10)     | NO   | PRI | 0       |       |
| name    | varchar(10) | YES  |     | NULL    |       |
| cardid  | int(18)     | YES  |     | NULL    |       |
| phone   | int(11)     | YES  |     | NULL    |       |
| address | varchar(50) | YES  |     | NULL    |       |
| remark  | text        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
|
25天前
|
数据库 索引
深入探索数据库索引技术:回表与索引下推解析
【10月更文挑战第15天】在数据库查询优化的领域中,回表和索引下推是两个核心概念,它们对于提高查询性能至关重要。本文将详细解释这两个术语,并探讨它们在数据库操作中的作用和影响。
44 3
|
12天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
39 3
|
13天前
|
存储 关系型数据库 MySQL
MySQL 字段类型深度解析:VARCHAR(50) 与 VARCHAR(500) 的差异
在MySQL数据库中,`VARCHAR`类型是一种非常灵活的字符串存储类型,它允许存储可变长度的字符串。然而,`VARCHAR(50)`和`VARCHAR(500)`之间的差异不仅仅是长度的不同,它们在存储效率、性能和使用场景上也有所不同。本文将深入探讨这两种字段类型的区别及其对数据库设计的影响。
27 2
|
17天前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发深度解析####
本文作为技术性文章,深入探讨了PHP与MySQL结合在动态网站开发中的应用实践,从环境搭建到具体案例实现,旨在为开发者提供一套详尽的实战指南。不同于常规摘要仅概述内容,本文将以“手把手”的教学方式,引导读者逐步构建一个功能完备的动态网站,涵盖前端用户界面设计、后端逻辑处理及数据库高效管理等关键环节,确保读者能够全面掌握PHP与MySQL在动态网站开发中的精髓。 ####
|
21天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
100 1
|
22天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
51 0
|
12天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
26 1
|
14天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
29 4
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
63 3
Mysql(4)—数据库索引

推荐镜像

更多