MySQL存储引擎以及索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL存储引擎以及索引

一、数据库引擎

1. 查看数据库引擎


mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
2. 查看表结构

show create table [student]:查看表结构,其中表使用的数据库引擎和字符集等可以在配置文件中修改。windows下的配置文件为安装目录下的my.ini,linux则在/etc/mysql/my.cnf

image.png

3. 查看表相关文件

表相关文件目录:/var/lib/mysql

  • 使用MyISAM存储引擎的表对应的文件有三个:*.frm*.MYD*.MYI,分别表示表结构、表数据、表索引
  • 使用InnoDB存储引擎的表对应的文件有两个:*.frm*.ibd,分别表示表结构、表数据和表索引,数据和索引放在一个文件中

image.png

面试问题:为什么使用InnoDB存储引擎的表会自动生成主键,而使用MyISAM存储引擎的表不会自动生成主键?

因为MyISAM的数据和索引是单独存放的,手动加上主键会生成主键索引存放在*.MYI,没有主键的话*.MYI里就不用存放索引。而InnoDB会默认生成一个整型类型的索引,因为Innodb的数据和索引放在一个文件中,数据就是放在索引树上的,没有索引,数据也没有地方存放。

4. 各存储引擎的区别
种类 锁机制 B树索引 哈希索引 外键 事务 索引缓存 数据缓存
MyISAM 表锁 支持 不支持 不支持 不支持 支持 不支持
InnoDB 行锁 支持 不支持 支持 支持 支持 支持
Memory 表锁 支持 支持 不支持 不支持 支持 支持
  • 锁机制:表示数据库在并发请求访问的时候,多个事务在操作时,并发操作的力度,能用行锁解决,就别用表锁,锁粒度大了降低并发度
  • B树索引和哈希索引:主要是加速SQL的查询速度
  • 外键:子表的字段依赖父表的主键,设置两张表的依赖关系
  • 事务:多个SQL语句,保证它们共同执行的原子操作,要么成功要么失败,不能只成功一部分,失败需要回滚事务
  • 索引缓存和数据缓存:和MySQL Server的查询缓存相关,索引是存放在磁盘上的,在没有对数据和索引做修改之前,重复查询可以不用进行磁盘I/O(数据库的性能提升,目的是减少磁盘I/O提升访问效率),读取上一次内存中查询的缓存就可以了

二、MySQL索引

当表中的数据量达到上百万的时候,SQL查询花费的时间会很长,需要使用索引加速SQL查询

由于 索引也是需要存储成索引文件的,因此使用索引也会涉及磁盘I/O操作。如果索引过多,使用不当,SQL查询时会造成大量无用的磁盘I/O操作,降低查询效率。

此外,我们 改动数据以后,不仅是数据文件需要做修改,索引文件也需要修改,索引过多,修改的索引也会更多,所以索引并不是越多越好。

1. 索引分类

索引是创建在表上的,是对数据库表中一列或多列的值进行排序的一种结果,其核心就是提高查询的速度

  • 物理上分为:聚集索引、非聚集索引
  • 逻辑上分为:
  1. 普通索引:没有任何限制条件,可以给任何字段创建普通索引(一张表的一次SQL查询只能使用一个索引,比如where age=1 and sex="man"只能使用一个索引)
  2. 唯一性索引:使用unique修饰的字段,值不能重复,主键索引就是一种唯一性索引
  3. 主键索引:使用PRIMARY KEY修饰的索引,主键字段会自动创建索引
  4. 单列索引:在一个字段上创建索引
  5. 多列索引:在表的多个字段上创建索引 (uid+cid,age+name等,先按第一个字段排序,再按第二个字段排序),多列索引必须使用到第一个列,才能用到多列索引,否则索引用不上,比如对于uid+cid的索引,我们这样where cid=2是无法使用该索引的
  6. 全文索引:使用FULLTEXT参数可以设置全文索引,只支持CHARVARCHARTEXT类型的字段上,常用于数据量较大的字符串类型上(真实项目中使用的较少,比如我们使用百度,肯定不会在数据库搜索文本,而是使用ElasticSearch等搜索引擎加速搜索)
  • 索引的优点:提高查询效率
  • 索引的缺点:索引并不是越多越好,过多的索引会导致CPU使用率居高不下,数据的改变也会造成索引文件的改变,过多的磁盘I/O造成CPU负载太重
2. 索引的创建和删除

创建表的时候指定索引字段:


CREATE TABLE student(id INT, 
  name VARCHAR(50), 
  sex ENUM('male', 'female'), 
  INDEX(id));

在已经创建的表上添加索引:


CREATE [UNIQUE] INDEX 索引名 ON 表名(属性名(length) [ASC | DESC]);

length表示用该字段的前length个字符建索引,如果字段很长,索引文件就会很大,搜索也慢,如果前length个字符可以区分该字段,就可以使用前length个字符建立索引

删除索引:


DROP INDEX 索引名 ON 表名;

此时表结构如下:


show create table student \G

image.png

使用具有主键索引的id进行过滤查找:


explain select * from student where uid=3;

image.png

从索引树上直接获取数据,并没有整表扫描,对于当前uid创建了索引,无论查询uid是多少的信息,都能在索引树上取得,直接命中

使用没有索引的name属性扫描


explain select * from student where name="zhangsan";

image.png

就算zhangsan排在第一个,也需要整表扫描,不扫描完,不知道其他行有没有zhangsan

给name添加索引


create index nameidx on student(name);

image.png

用name索引加速搜索

image.png

  • type为ref,表示在扫描索引树;若type为const,表示使用主键索引或唯一性索引,直接精确匹配
  • key_len这里是152,对于给字符串类型数据建立索引的时候,一般会限制索引长度。若前面一部分字符区可以用于区分不同的数据,没必要使用很长长度的索引(key_len很大)。因为索引长了,索引文件会变大,就会使用更多的磁盘IO,应尽量避免

然而添加索引后,不一定就能使用到索引,因为MySQL server有优化,它会先进行分析,如果发现使用索引需要扫描的数据基本上是所有数据的大概百分之七八十左右,其实是不会使用索引的,因为如果花费差不多,读索引文件花费磁盘I/O,还要扫描索引树,还不如直接整张表搜索取数据

3. 关于缓存问题

image.png

image.png

对于相同的操作,若中间没有更新数据(insert/delete/update),则第一次花费时间长,第二次花费时间短,这是因为存储引擎对索引和数据进行了缓存。  第一次查询后的结果会放在数据缓存或者索引缓存里,第二次就不用花费磁盘I/O从磁盘读取索引了。

4. 过滤条件字段涉及类型转换则无法使用索引

image.png

查看表结构后发现,password属性是varchar,然而查询的时候使用的是int,这就涉及到了类型转换,所以不会使用索引。此外,如果用到了mysql的聚集函数或表达式计算,也不会用到索引

image.png

5. 删除索引


drop index pwdidx on t_user;
6. explain字段含义
  • select_type

image.png

  • table

image.png

  • type

image.png

  • ref

image.png

  • Extra

image.png

7. 加索引优化原则
  • 若经常作为过滤条件(where)的属性,需要加上索引
  • 给字符串属性添加索引的时候,最好根据字段前面一部分字符创建索引即可,即限制索引的长度(key_len)
  • where过滤条件使用的索引字段涉及类型强转、mysql聚合函数调用、表达式计算等,则不会使用索引


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
2月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
95 4
|
4月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
6月前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
2月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
|
3月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
115 9
|
4月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
105 12
|
4月前
|
存储 SQL 关系型数据库
MySQL存储引擎简介
在选择相应的存储引擎时,需要充分考虑实际业务场景、性能需求和数据一致性要求,从而为数据管理提供最佳支持。
296 17
|
5月前
|
SQL 存储 关系型数据库
MySQL选错索引了怎么办?
本文探讨了MySQL中因索引选择不当导致查询性能下降的问题。通过创建包含10万行数据的表并插入数据,分析了一条简单SQL语句在不同场景下的执行情况。实验表明,当数据频繁更新时,MySQL可能因统计信息不准确而选错索引,导致全表扫描。文章深入解析了优化器判断扫描行数的机制,指出基数统计误差是主要原因,并提供了通过`analyze table`重新统计索引信息的解决方法。
135 3
|
6月前
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。

推荐镜像

更多