【MySQL】索引和事务

索引

一. 索引的重要性

MySQL 的索引就是数据结构,能够对多列的值进行排序来更快的进行查询数据。索引就像是一本书的目录,通过目录我们可以快速定位到数据所在的位置。无需扫描整张表来找数据。

虽然查询速度变快了,但是与之而来的是读写操作增加了更多的IO,但是为了提高检索速度是值得的。

二. 理解索引

要想知道为何添加索引之后可以更快的查询数据,我们就得理解索引。

首先明确,MySQL的操作都是在内存当中进行的,它的任务就是对数据进行CURD操作。那么数据是保存在磁盘的。MySQL与磁盘进行IO交互时通过一个个page进行的。page是内存与磁盘交互的最小单位。page的目的在于一次性多加载,以达到减少IO的目的。相比于要多少加载多少可以有效减少IO次数。

那MySQL是怎么提升自己的查询速度的呢?

通过索引数据结构。MySQL采用B+树的结构,类似与多叉树,根结点存储page目录用于定位所要信息的page处,叶子结点存储数据信息。这些数据是通过索引进行排序的,都是有序的。

整个查找的办法我们可以类比于找数字。例如我现在要找一个数字52,首先我通过树结构先找到50-60范围的起始点50,然后从50向60进行遍历找到52。

根结点存储page页的指针,page页存储着实际存储数据的page指针,接着就是存储数据的page。

三. 索引操作

1. 创建索引

创建索引有三种方式,第一种直接跟在列后面,第二种在最后面指定列,第三种创建完表后对指定列添加索引

主键索引案例:

唯一键索引案例:

普通索引案例:

2. 查询索引

show 【索引】from【表】

案例:

3. 删除索引

删除主键索引

alter table【表】drop primary key;

删除其他索引

alter table 【表】drop 【索引名】


事务

一. 什么是事务

事务是数据库操作的逻辑执行单元,这些操作要么全部实现,要么全部失败回滚。

为的就是保证数据的一致性和完整性。

事务必须满足四个特性(ACID)

原子性

事务是一个整体,要么全部成功要么全部失败回滚,例如转账时A账户扣钱和B账户加钱必须同时成功。

一致性

执行前后,数据库状态要保持一致,如转账后两个账户总金额不变。

隔离性

多个事务并发执行,彼此间的操作不能互相干扰

持久性

事务一旦提交,结果就是永久性的,即使系统崩溃数据也不会丢失。

二. 事务提交方式

事务提交就是将事务执行的操作永久保存到数据库并且释放锁,主要有显示提交和隐式提交

显示提交

显示提交是使用了 commit 进行手动提交事务

隐式提交

隐式提交涉及到MySQL的autocommit模式,当autocommit = on 时代表隐式模式开启,每条SQL语句都会被自动提交。当 autocommit = off 时就默认为显示提交

我们可以查看autocommit并且进行修改

show variables like 'autocommmit'

set autocommit = (1开 / 0关)

案例:

三. 事务操作方式

正常处理事务

通过begin开始事务,commit结束事务,savepoint【名字】可以暂存点,rollback【名字】可以进行回档。

案例:


当我们开启两台终端时,隔离级别为未读提交,当我们在终端a插入数据但为commit,此时在终端b访问表就无法查看到数据

案例:


当我们对事务进行commit后,此时中断主机A,在主机B上查询表可以发现依然能看到commit前插入的数据。说明commit将数据永久保存在数据库中

案例:


关闭autocommit,当我们向主机A表中插入数据时,主机B也会同步更新表。当主机A在未commit下突然崩溃,表会自动进行回滚

四. 事务隔离级别

隔离性就是多个操作之间互不干扰的状态。

事务的隔离等级分为四种:读未提交,读提交,可重复读,串行化

查看与设置隔离性

查看全局隔离级别

SELECT @@global.transaction_isolation;

查看当前会话全局隔离级别

SELECT @@transaction_isolation;

当前会话只影响当前数据库的隔离级别,全局会话会设置默认的新链接

案例:


设置当前会话隔离级别

set 【session/global】transaction isolation level 【read uncommitted | read committed | repeatable read | serializable】

设置为全局或者当前会话,设置等级为四个

案例:


读未提交

当我们使用读未提交时,主机A和主机B同时begin开始事务,主机A更新数据库一条数据,但是未commit,此时主机B访问表可以实时查看到数据被更改

案例:

一个事务在执行中,读到另一个执行中事务的更新但是未commit数据,这种现象叫做脏读
读提交

我们让主机A和主机B同时开启一项事务,主机A对列更新但未保存,此时主机B访问该列拿到的是久值。主机B倘若对就值进行处理,此时主机A对该列进行commit,就会造成读取到了不同的值

案例:

这种现象就是不可重读读
可重读读

同时开启主机A和主机B的事务,主机A更改某列数据,此时主机B访问表发现表仍然为原先旧数据;主机A进行commit保存数据,主机B再次访问,发现仍然为原先数据;主机B进行commit保存数据,此时再进行访问表,表才进行了更新。

案例:

倘若我们主机A更改列后不进行commit,此时主机B对该列进行修改,那么此时就会卡住,直到主机Acommit后主机B更改才能成功。

这也就导致我们插入数据不断查询的过程中值在不断地变化,如同产生幻觉,这就是幻读
串行化

同时开启主机A和主机B,当主机A对表进行修改时,此时主机B访问该表就会造成阻塞,直到主机A进行commit后,主机B才会显示

案例:

串行化虽然说隔离级别最严格,但也伴随着效率是其中最低下的那一种方式


隔离级别是一致性与性能的权衡,级别越高,一致性越好,但性能也会越差。

相关推荐
小北方城市网31 分钟前
第 9 课:Python 全栈项目性能优化实战|从「能用」到「好用」(企业级优化方案|零基础落地)
开发语言·数据库·人工智能·python·性能优化·数据库架构
ChineHe32 分钟前
Redis入门篇001_Redis简介与特性
数据库·redis·缓存
仓颉也为难32 分钟前
全表扫和索引在哪种场景哪个效率高、基线分水岭在哪
数据库
Anthony_23134 分钟前
MySql常用SQL命令
服务器·数据库·sql·mysql·http·oracle·udp
一直在追38 分钟前
大数据转型的“降维打击”:当分布式架构遇上向量数据库 (Milvus & ES 实战)
大数据·数据库
E_ICEBLUE43 分钟前
PPT 智能提取与分析实战:把演示文档变成结构化数据
数据库·python·powerpoint
困知勉行19851 小时前
Redis数据结构及其底层实现
数据库·redis·缓存
一直在追1 小时前
告别 WHERE id=1!大数据工程师的 AI 觉醒:手把手带你拆解向量数据库 (RAG 核心)
大数据·数据库
Gofarlic_OMS1 小时前
协同设计平台中PTC许可证的高效调度策略
网络·数据库·安全·oracle·aigc
刘一说1 小时前
Windows 与 Linux 跨平台自动化 MySQL 8 备份:专业级脚本设计与实战指南
linux·数据库·windows·mysql·自动化