Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql索引、存储引擎、事务、锁机制和优化

mysql中的索引、存储引擎、事务、锁机制和优化详解

作者:墨尘儿

这篇文章主要介绍了mysql中的索引、存储引擎、事务、锁机制和优化,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. MySQL的索引

1.1 概述

索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有以特定值的行,不使用索引,MySQL必须从一条记录开始读完整个表,直到找出相关的行,表越大查询数据所花的时间越多,如果表中查询的列有一个索引,MySQL能够快速达到一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。

1.2 分类

索引是存储引擎用来快速查找记录的一种数据结构:

1.3 特点

优点

缺点

创建索引的原则

2. 存储引擎——MySQL的核心

存储引擎就是存储数据、建立索引、更新、查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可以被称为表类型。

2.1 分类

功能MyISAMMEMORYInnoDB
存储限制256TBRAM64TB
支持事务NoNoYes
支持全文索引YesNoNo
支持B树索引YesYesYes
支持哈希索引NoYesNo
支持集群索引NoNoYes
支持数据索引NoYesYes
支持数据压缩YesNoNo
空间使用率N/A
支持外键NoNoYes
支持锁机制表锁表锁表锁/行锁

3. MyISAM和InnoDB

MyISAM和InnoDB都是MySQL数据库中常见的存储引擎,各自特点和使用场景如下:

MyISAM

特点

使用场景

InnoDB

MySQL默认的事务型引擎。

特点

使用场景

在存储引擎时,需要根据应用的具体需求来决定使用哪种引擎。如果是简单的应用,只需要基本的增删改查功能,可以选择MyISAM。

如果需要支持事务、并发性能较高或者有复杂的数据关系,建议选择InnoDB。

MyISAMInnoDB
事务不支持支持
表锁表锁、行锁
文件存储3个1个
外键不支持支持

4. 事务

4.1 特性(ACID)

4.2 事务靠什么保证

4.3 undo log和redo log的区别

缓冲池(buffer pool):主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从主磁盘加载并缓存),以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。

数据页(page):是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16KB,液中存储的是行数据。

redo log:

undo log:

:排他锁(如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁)

MVCC:多版本并发控制

4.4 事务的隔离级别

高并发情况下,并发事务会产生脏读、不可读重复、幻读等问题,这时需要用隔离级别来控制。

InnoDB默认隔离级别为可重复读级别,分为快照读和当前读,并且通过间隙锁解决了幻读问题。

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
读提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

4.5 事务的并发问题

脏读:事务A读取了事务B更新的数据,然后事务B回滚操作,那么事务A读取到的数据是脏数据。

不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。

幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这时插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,就成为幻读。

如何解决脏读、幻读、不可重复读

4.6 快照读和当前读

4.7 MVCC

MVCC是多版本并发控制,为每次事务生成一个新版本数据,每个事务都有自己的版本,从而不加锁就解决读写冲突,这种读为快照读。只在读已提交和可重复读中生效。

实现的原理由以下四项保证

5. 锁机制

5.1 定义

锁是计算机协调多个进程或线程并发访问某一资源的机制(避免竞争)。在数据库中,除传统的计算资源(如CPU,RAM,I/O等)的争用外,数据也是一种供许多用户共享的资源。

锁机制能保证数据并发访问的一致性、有效性,同时也影响数据库并发访问性能。

5.2 分类

根据对数据操作的粒度

锁类型特点
表级锁偏向MyISAM存储引擎,开销大,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁。锁粒度最小,发生锁冲突的概率最低,并发度也最高。

根据对数据操作的类型

存储引擎表级锁行级锁
MyISAM支持不支持
InnoDB支持支持
MEMORY支持不支持
BOB支持不支持

6. 日志

分类:错误日志、二进制日志、查询日志、慢查询日志

6.1 错误日志

SHOW variables LIKE 'log_error%'

6.2 二进制日志

二进制日志(BINLOG)记录了所有的DDL语句和DML语句,但不包括DQL语句。此日志对灾难时的数据恢复起着极其重要的作用,MySQL的主从复制就是通过改BINLOG实现的。

二进制日志在MySQL8默认开启,低版本需要通过配置文件开启,并配置MySQL日志的格式。

Windows系统:my.ini Linux系统: my.cnf

6.3 查询日志

查询日志中记录了客户端的所有操作语句,而二进制日志不包含查询数据的SQL语句。

默认情况下,查询日志是未开启的。

6.4 慢查询日志

慢查询日志记录了所有执行时间超过参数long_query_time设置值并且扫描记录数不小于min_examined_row_limit的所有SQL语句的日志。long_query_time默认为10秒,最小为0,精度可以到微秒。

7. 索引

7.1 定义

索引(index)是帮助MySQL高效的获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构(B+树),这些数据结构以某种方式指向数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。这样可以提高数据检索的效率,降低数据库的IO成本(不需要全表扫描)。通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

B树与B+树对比

7.2 聚簇索引和非聚簇索引

7.2.1 聚簇索引

7.2.2 二级索引(非聚簇索引)

7.2.3 聚簇索引选取规则

7.2.4 回表查询

(首先介绍聚簇索引和非聚簇索引,然后介绍回表查询)

通过二级索引找到对应的主键值,到聚簇索引中查找整行数据,这个过程就是回表。

7.3 覆盖索引

覆盖索引是指查询使用了索引,并且需要返回的列在该索引中已经全部能够找到。

(可以使用索引覆盖解决MySQL超大分页)

7.4 MySQL超大分页处理

7.5 创建索引的原则

7.6 什么情况下索引会失效?

8. 优化

SQL优化一般可以从设计、查询、索引和存储四方面进行。

8.1 如何定位慢查询?

8.2 一个SQL语句执行很慢,如何分析

可以使用MySQL自带的分析工具EXPLAIN或者DESC

通过key和key_len检查是否命中了索引(索引本身存在是否失效的情况)

通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描

通过extra建议判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复。

type:这条SQL的连接类型,性能由好到差依次为:NULL,system,const,eq_ref,ref,range,index,all

extra含义
Using where;Using index查找使用了索引,需要的数据都在索引列中能找到,不需要回表查询数据
Using index condition查找使用了索引,但是需要回表查询数据

8.3 SQL优化的经验

表的设计优化

参考阿里开发手册《嵩山版》

索引优化[参考优化创建原则和索引失效]

SQL语句优化

主从复制、读写分离

如果数据库的使用场景读的操作比较多的时候,为了避免写的操作所造成的性能影响,可以采用读写分离的架构,读写分离解决的是数据库的写入,影响了查询的效率。

分库分表

8.4 主从同步原理

MySQL主从复制的核心是二进制bin log(记录DDL和DML)

8.5 分库分表

时机

拆分策略

垂直拆分

垂直分库:以表为依据,根据业务将不同表拆分到不同库中

特点

垂直分表:以字段为依据,根据字段属性将不同字段拆分到不同表中

特点

水平拆分

水平分库:将一个库的数据拆分到多个库中

特点

水平分表:将一个表的数据拆分到多个表中(可以在同一个库内),按照记录分表

特点

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文