电话:13485538018
关闭
您当前的位置:首页 > 职场资讯 > 面试秘籍

面试必看:SQL查询执行顺序与事务ACID详解

来源:网络整理 时间:2026-04-24 作者:佚名 浏览量:

Select 语句完整的执行顺序

SQL Select 语句完整的执行顺序:

(1) from 子句组装来自不同数据源的数据;

(2) where 子句基于指定的条件对记录行进行筛选;

(3) group by 子句将数据划分为多个分组;

(4) 使用聚集函数进行计算;

(5) 使用 having 子句筛选分组;

(6) 计算所有的表达式;

(7) select 的字段;

(8) 使用 order by 对结果集进行排序。

MySQL 事务

事务的基本要素 (ACID)

原子性,也就是Atomicity,事务开启之后的所有操作,要么是全部完成,要么是统统不做,绝不可能在中间环节出现停滞情况。事务在执行进程里要是出错,就会回滚到事务起始之前的状态,所有的操作仿若未曾发生过一样。这就是说事务是一个不可拆分的整体,恰似化学课上学到的原子,乃是物质构成的基本单元。

一致性,也就是Consistency,在事务开始之前以及结束之后,数据库的完整性约束并未遭到破坏,举例来说,像是A向B进行转账这种情况,绝不可能出现A扣了钱,然而B却没有收到的状况。

隔离性也就是说,同一时刻之际,所遵循的条件是只能够有一个事务去请求同一数据,并且不同的事务相互之间不存在任何彼此干扰的情况。举例来说,当A正在从一张银行卡里进行取钱操作时,在A取钱这个操作过程结束之前,B是不可以向这张卡进行转账操作的句号。

存续持续性(Durability),于事务完结之后,事务针对数据库的全部更新会被留存至数据库,无法进行回滚。

MySQL 事务隔离级别:

事务的并发问题

数据读取存在脏读情况,即事务A读取了事务B更新之后的数据,之后事务B进行了回滚操作,如此一来,事务A所读取到的数据便属于脏数据。

不可重复读:事务 A 进行了多次对于同一数据的读取操作,事务 B 处于事务 A 的多次读取这个过程当中。

这里,于数据之上进行了更新操作而后提交,致使事务A在多次去读取同一数据之际,所获结果呈现出不一致的状况。

幻读,系统管理员 A,把数据库里所有学生的成绩,从具体分数,改成了 ABCDE 等。

首先,系统管理员A进行了一系列操作使数据处于某种状态,这是一个情况。接着,系统管理员B在这个特定的时候插入了一条带着具体分数的记录,形成了新的情况。然后,当系统管理员A完成修改操作结束后,惊奇地发现仍有一条记录是没有被处理过来的,这又出现了新状况。就仿佛如同发生了那种令人迷惑犹如产生幻觉一般的莫名状态,而这种现象,这就被称作幻读。

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

读脏:将隔离级别设定成读提交,把隔离级别设置为可重复读,把隔离层次确定为串行化,这些情况之下能够解决读脏。

不可以进行重复读取,隔离的等级是可重复读取,串行化能够将不可重复读取的问题给解决掉。

幻读,隔离级别要是设成串行化的话,是能够解决幻读问题的,借助MVCC加上区间锁呢,也能够把幻读给解决掉。

小结:

MySQL事务ACID特性_面试常用sql语句_SQLSelect语句执行顺序

和幻读很难分清容易混淆导致其不可重复读,这当中不可重复读偏向于进行修改,而幻读聚焦于新增或者删除。解决不可重复读的问题只要把满足条件的行锁住就行,解决幻读则得锁定表。

MyISAM和 InnoDB 的区别

悲观锁和乐观锁的怎么实现

选出来的内容,为了更新,是MySQL所给出的,用来实现悲观锁的方式,这种方式是select...for update。

例如:

从物品表中选取价格列为价格,条件是物品编号等于100,并执行排它锁操作 ,在items表里面,编号为100的那一条数据此刻被我们锁定了。其他需要执行从物品表中选取价格列为价格,条件是物品编号等于100,并执行排它锁操作的事务必须等待本次事务提交完成之后才能去执行。如此一来我们能够确保当前的数据不会被其他事务进行修改。MySQL存在这样一个问题,select...for update语句执行期间,所有扫描过的行都会被加上锁,所以在MySQL里使用悲观锁务必要确定走了索引,而非进行全表扫描,不然将会把整个数据表锁住。

乐观锁,相对悲观锁来说,它觉得数据通常情况下不会引发冲突,所以在数据开展提交更新之时,才会正式针对数据的冲突与否展开检测,要是发觉冲突了,那就返回错误信息,让用户自行决定该怎么做。利用数据版本号(version)机制是乐观锁最为常用的一种实现途径。通常借助给数据库表增添一个属于数字类型的“version”字段,在进行数据读取操作之际,把“version”字段的数值一块儿读取出来,每当数据产生一次更新行为,针对此“version”值进行加一操作。在我们提交更新之际,要去判断数据库表对应的记录的当前版本信息,将其与第一次取出来的version值做比对,要是数据库表当前版本号跟第一次取出来的version值相等,那就予以更新,不然的话就认定为是过期数据,返回更新失败。

举例:

//1: 查询出商品信息

从名为 items 的表中,选取出当 id 等于 100 时的 quantity 和 version ,进行查询操作。

//2: 根据商品信息生成订单

往订单表中插入数据,订单表的字段有编号、商品编号,所插数据中编号的值为空,商品编号的值为一百。

//3: 修改商品的库存

第一,把物品表中的数量字段的值,改成其自身减去一;第二,将物品表中的版本号字段的值,变为其自身加上一;第三,给定一个条件用于筛选,即物品表中的记录的id字段的值等于一百,并且版本号字段的值等于版本参数;第四,基于前面的条件,对物品表中符合该行的这个指定的记录进行更新操作。

聚簇索引与非聚簇索引区别

都是 B+树的数据结构

聚簇索引,它把数据存储和索引放置到了一块,并且是以一定的顺序进行组织的,一旦找到索引,也就能够找到数据,数据的物理存放顺序跟索引顺序是一致的,也就是说,只要索引是相邻的,那么对应的数据必然也是相邻地存放在磁盘之上的。

非聚簇索引,叶子节点所存储的并非数据,而是数据行地址,这意味着依据索引查找时,需先找到数据行的位置,之后再前往磁盘查找数据,这种情况有点类似于一本书的目录,举例来说,当我们想要查找第三章第一节时,首先要在这个目录里面进行查找,待找到对应的页码后,再去到对应的页码去查看文章。

优势:

查询时,通过聚簇索引能够直接获取数据,而非聚簇索引在非覆盖索引的情形下,需要进行第二次查询,相比之下,聚簇索引的效率更高。

2、聚簇索引在范围查询方面效率颇高,这是由于其数据系依据大小予以排列的。

3 、聚簇索引适合用在排序的场合, 非聚簇索引不适合

劣势:

1、维护索引代价高昂,尤其是在插入新行,或者主键更新致使需要分页,即pagesplit时。建议于大量插入新行之后,挑选负载较低的时段,借助OPTIMIZETABLE对表进行优化,因为必定会被移动的行数据有可能导致碎片。采用独享表空间能够减轻碎片。

2、不要因为将 uuId(也就是随机 ID)用作主键,致使数据存储呈现稀疏状态,如此一来就会出现聚簇索引有可能比全表扫描还要慢的情况,故而建议采用 int 的 auto_increment 当作主键。

3、要是主键相对较大,那么辅助索引会变得更大,因辅助索引的叶子所存储的是主键值,过长的主键值会致使非叶子节点占用更多的物理空间。

微信扫一扫分享资讯
客服服务热线
13485538018
24小时服务
微信公众号
手机浏览

CopyrightC 2009-2025 All Rights Reserved 版权所有 芜湖人才网 本站内容仅供参考,不承担因使用信息、外部链接或服务中断导致的任何直接或间接责任,风险自担。如有侵权,请联系删除,联系邮箱:ysznh@foxmail.com 鄂ICP备2025097818号-15

地址: EMAIL:qlwl@foxmail.com

Powered by PHPYun.

用微信扫一扫