MySQL面试
文章目录
- 事务隔离级别
- 需要解决的问题
- 事务隔离级别
- MySQL 中是如何实现事务隔离的
- 实现可重复读
- 什么是存储引擎
- 如何定位慢查询
- 分析慢查询原因
- MySQL超大分页怎么处理
- 索引失效
- 什么时候建立唯一索引、前缀索引、联合索引?
- redolog与binlog是如何保证一致的
- redolog刷盘时机
- undo日志什么时候删除?
- binlog 、redolog分别在什么层
- 意向锁
- MySQL数据类型
- 关键字书写顺序和执行顺序
- MySQL查询缓存
- Buffer Pool中是如何管理Page页
- SELECT COUNT(*) 在哪个引擎执行更快?
- count(*) 和 count(1)和count(列名)区别
- binlog记录的一定是sql语句吗
- Redo Log 的刷盘时机
- 怎么将一条 SQL 加载到缓冲池和记录哪些日志的
- 如何优化mysql分页查询
- MySQL加锁的基本单位
- on 和 where 的区别
- 为什么不建议为区分度不高字段建立索引
- 一条update更新语句的执行流程
- MySQL执行一条Select语句是怎么运行的?
- 为什么不用memory
链接
MySQL基础篇
MySQL原理篇
事务隔离级别
需要解决的问题
脏读
脏读指的是读到了其他事务未提交的数据
可重复读
可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。
不可重复读
对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新(UPDATE)操作。
幻读
幻读是针对数据插入(INSERT)操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读。
事务隔离级别
读未提交
MySQL事务隔离其实是依靠锁来实现的,加锁自然会带来性能的损失。而读未提交隔离级别是不加锁的,所以它的性能是最好的,没有加锁、解锁带来的性能开销。
读提交
读提交就是一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用 commit命令之后的数据。那脏数据问题迎刃而解了。读提交事务隔离级别是大多数流行数据库的默认事务隔离界别,比如 Oracle,但是不是 MySQL 的默认隔离界别。每个 select 语句都有自己的一份快照,而不是一个事务一份,所以在不同的时刻,查询出来的数据可能是不一致的。
可重复读
可重复读是指,事务不会读到其他事务对已有数据的修改,及时其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入的数据是可以读到的,这也就引发了幻读问题。
串行化
串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行
MySQL 中是如何实现事务隔离的
首先说读未提交,它是性能最好,因为没加锁。
再来说串行化。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。
最后说读提交和可重复读。
实现可重复读
为了解决不可重复读,或者为了实现可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。
我们在数据库表中看到的一行记录可能实际上有多个版本,每个版本的记录除了有数据本身外,还要有一个表示版本的字段,记为 row trx_id
,而这个字段就是使其产生的事务的 id,事务 ID 记为 transaction id
,它在事务开始的时候向事务系统申请,按时间先后顺序递增。
按照上面这张图理解,一行记录现在有 3 个版本,每一个版本都记录这使其产生的事务 ID,比如事务A的transaction id 是100,那么版本1的row trx_id 就是 100,同理版本2和版本3。
在上面介绍读提交和可重复读的时候都提到了一个词,叫做快照,学名叫做一致性视图,这也是可重复读和不可重复读的关键,可重复读是在事务开始的时候生成一个当前事务全局性的快照,而读提交则是每次执行语句的时候都重新生成一次快照。
对于一个快照来说,它能够读到那些版本数据,要遵循以下规则:
- 当前事务内的更新,可以读到;
- 版本未提交,不能读到;
- 版本已提交,但是却在快照创建后提交的,不能读到;
- 版本已提交,且是在快照创建前提交的,可以读到;
利用上面的规则,再返回去套用到读提交和可重复读的那两张图上就很清晰了。还是要强调,两者主要的区别就是在快照的创建上,可重复读仅在事务开始是创建一次,而读提交每次执行语句的时候都要重新创建一次。
什么是存储引擎
存储引擎是数据库底层的组件,是数据库的核心。
使用存储引擎可以创建、查询、更新、删除数据库。存储引擎可以理解为数据库的操作系统,不同的存储引擎提供的存储方式、索引机制等也不相同
如何定位慢查询
方案一:开源工具
- 调试工具:Arthas
- 运维工具:Prometheus、Skywalking
方案二:MySQL自带慢日志
查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志如果要开启慢查询日志,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
# 开启MySQL慢日志查询开关
slow_query_log=1
# 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
分析慢查询原因
可以采用 EXPLAIN 或者 DESC 命令获取 MySQL 如何执行 SELECT 语句的信息。语法
-- 直接在select语句之前加上关键字 explain/desc
explain select 字段列表 from 表名 where 条件;
可以采用MySQL自带的分析工具 EXPLAIN 去查询这条sql的执行情况
- 通过key和key_len检查是否命中了索引(索引本身存在、是否有失效的情况)
- 通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描
- 通过extra建议判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复
MySQL超大分页怎么处理
可以使用覆盖索引解决。
问题:在数据量比较大时,limit分页查询,需要对数据进行排序,效率低
因为,当在进行分页查询时,如果执行 limit 9000000,10 ,此时需要MySQL排序前9000010 记录,仅仅返回
9000000 - 9000010 的记录,其他记录丢弃,查询排序的代价非常大 。解决方案:覆盖索引+子查询。先分页查询数据的id字段,确定了id之后
再用子查询来过滤,只查询这个id列表中的数据就可以了。因为查询id的时候 走的覆盖索引,所以效率可以提升很多
索引失效
什么时候建立唯一索引、前缀索引、联合索引?
前缀索引
考虑一个文章表articles,其内容字段content非常大:
为了减少索引空间占用并加速对title列的模糊查询,我们可以只对title的前几个字符创建前缀索引:
唯一索引
列已经是一个主键,自动带有唯一约束。如果还需要确保逐渐的唯一性,可以添加一个唯一索引:
联合索引
- 减少开销。
建一个联合索引(col1,col2,col3),实际相当于建了(col1),(col1,col2),(col1,col2,col3)三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销! - 覆盖索引。
对联合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io操作。减少io操作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之
redolog与binlog是如何保证一致的
InnoDB存储引擎使用两阶段提交方案。
原理很简单,将redo log的写入拆成了两个步骤prepare和commit,这就是两阶段提交。
使用两阶段提交后,写入binlog时发生异常也不会有影响,因为MySQL根据redo log日志恢复数据时,发现redo log还处于prepare阶段,并且没有对应binlog日志,就会回滚该事务。
redolog刷盘时机
理想情况下,事务一提交就会进行刷盘操作,但是实际上是刷盘的时机是根据策略来决定的。 InnoDB存储引擎为redo
log的刷盘策略提供了innodb_flush_log_at_trx_commit参数,它支持三种策略:
- 0:设置为0的时候,每次提交事务时不刷盘。
- 1:设置为1的时候,每次提交事务时刷盘。
- 2:设置为2的时候,每次提交事务时都只把redo log buffer写入page cache。
innodb_flush_log_at_trx_commit参数默认为1,当事务提交的时候会调用fsync对redolog进行刷盘,将redo log buffer写入redo log文件中。
另外,Innodb存储引擎有一个后台线程,每隔1秒,就会把会redo log buffer中的内容写入到文件系统缓存page
cache,然后调用fsync刷盘。
undo日志什么时候删除?
insert类型的,在事务提交之后就可以清除掉了。
update类型的,事务提交之后不能立即清除掉,这些日志会用于mvcc。只有当readview中不存在这个事务的事务id时才能被删除。
binlog 、redolog分别在什么层
redo log(重做日志)是InnoDB存储引擎独有的
binlog日志是逻辑日志,记录内容是语句的原始逻辑,属于MySQL Server层
意向锁
innodb的意向锁主要用于解决多粒度的锁并存的情况。
要作用是处理行锁和表锁之间的矛盾,能够显示“某个事务正在某一行上持有了锁,或者准备去持有锁”
MySQL数据类型
关键字书写顺序和执行顺序
- 书写顺序
SELECT <字段名>
FROM <表名>
JOIN <表名>
ON <连接条件>
WHERE <筛选条件>
GROUP BY <字段名>
HAVING <筛选条件>
UNION
ORDER BY <字段名>
LIMIT <限制行数>;
- 执行顺序
1.FORM:选择from后面跟的表,产生虚拟表1。
2.ON:ON是JOIN的连接条件,符合连接条件的行会被记录在虚拟表2中。
3.JOIN:如果指定了LEFT JOIN,那么保留表中未匹配的行就会作为外部行添加到虚拟表2中,产生虚拟表3。如果有多个JOIN链接,会重复执行步骤1~3,直到处理完所有表。
4.WHERE:对虚拟表3进行WHERE条件过滤,符合条件的记录会被插入到虚拟表4中。
5.GROUP BY:根据GROUP BY子句中的列,对虚拟表2中的记录进行分组操作,产生虚拟表5。
6.HAVING:对虚拟表5进行HAVING过滤,符合条件的记录会被插入到虚拟表6中。
7.SELECT:SELECT到一步才执行,选择指定的列,插入到虚拟表7中。
8.UNION:UNION连接的两个SELECT查询语句,会重复执行步骤1~7,产生两个虚拟表7,UNION会将这些记录合并到虚拟表8中。
9.ORDER BY: 将虚拟表8中的记录进行排序,虚拟表9。
10.LIMIT:取出指定行的记录,返回结果集。
MySQL查询缓存
一、查询缓存的基本概念
MySQL 的查询缓存是一种用于存储查询结果的内存区域。当一个查询被执行时,MySQL首先检查查询缓存中是否已经存在相同的查询结果。如果存在,直接从查询缓存中返回结果,而无需再次执行查询语句,从而大大提高查询性能。
二、查询缓存的工作原理
- 缓存存储
查询缓存存储的是完整的查询语句和对应的查询结果。当一个查询被执行时,MySQL会将查询语句进行哈希计算,生成一个唯一的哈希值。这个哈希值作为查询缓存的键,查询结果作为值存储在缓存中。 例如,对于查询 SELECT *FROM users WHERE age > 30,MySQL 会计算这个查询语句的哈希值,并将查询结果与这个哈希值一起存储在查询缓存中。- 缓存命中判断
当一个新的查询到来时,MySQL同样会对查询语句进行哈希计算,然后在查询缓存中查找是否存在相同的哈希值。如果找到,并且查询语句和缓存中的查询完全一致(包括大小写、注释等),则认为是缓存命中,直接返回缓存中的结果。
例如,如果再次执行 SELECT * FROM users WHERE age > 30,MySQL会计算哈希值并在查询缓存中查找,发现有相同的哈希值且查询语句一致,就会从缓存中返回结果。- 缓存失效
查询缓存并不是永久有效的,当以下情况发生时,查询缓存会失效:
- 表数据发生变化:当查询涉及的表中的数据被插入、更新或删除时,与该表相关的所有查询缓存都会被标记为无效,并从缓存中移除。这是因为表数据的变化可能导致查询结果不再准确。
- 查询语句发生变化:即使是微小的变化,如添加注释、改变大小写等,也会导致查询缓存不命中。因为 MySQL 对查询语句的一致性要求非常严格。
- 缓存空间不足:当查询缓存的内存空间不足时,MySQL 会根据一定的算法淘汰一些旧的缓存数据,为新的查询结果腾出空间。
Buffer Pool中是如何管理Page页
Page页分类:在BP的底层采用的是链表数据结构管理Page。Page根据状态可以分为3中类型
- free Page:空闲Page,未被使用的Page。
- clean Page:被使用的Page,但是数据没有修改过。
- dirty Page:脏页,被使用过的Page,并且数据被修改了,缓存页中的数据与磁盘的数据不一致的。
上面说的三种Page类型,InnoDB采用三种链表结构进行维护和管理。
free list :表示空闲缓冲区,管理free Page
flush list:表示的是需要刷新到磁盘的缓冲区,管理dirty page,内部page是按照修改时间排序。
lru ist :表示正在使用的缓冲区,管理cean page和dity pae,该缓冲区以 midpoint 为基点,前面的链表称为new 列表区,存放经常被访问的数据,占63%,后面的链表称为old列表区,存放的是使用较少的数据占37%。
注意:脏页在fush链表和LRU链表中都存在,但是两者互不影响,LRU链表负责管理page的可用性和释放,而fush list负责管理脏页的刷盘操作
SELECT COUNT(*) 在哪个引擎执行更快?
select count(*)常用于统计表的总行数,在MyISAM存储引擎中执行更快,但前提是不加where条件。
因为MyISAM对于表的行数做了优化,内部用了一个变量存储表的行数,如果查询条件没有where条件,则MyISAM可以迅速返回结果,如果加上where语句就不行了。
InnerDB存储引擎也有一个存储了表行数的变量,但这个值是一个估计值,所以并没有什么实际意义。
count(*) 和 count(1)和count(列名)区别
执行效果上:
- count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略为NULL的值。
- count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略为NULL的值。
- count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是指空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。
执行效率上:
- 列名为主键,count(列名)会比count(1)快
- 列名不为主键,count(1)会比count(列名)快
- 如果表多个列并且没有主键,则 count(1 的执行效率优于 count(*)
- 如果有主键,则 select count(主键)的执行效率是最优的
- 如果表只有一个字段,则 select count(*)最优。
binlog记录的一定是sql语句吗
binlog 有三种格式:
- Statement(Statement-Based Replication,SBR):每一条会修改数据的 SQL 都会记录在 binlog 中。
- Row(Row-Based Replication,RBR):不记录 SQL 语句上下文信息,仅保存哪条记录被修改。
- Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合体。
Redo Log 的刷盘时机
- 事务提交
当事务提交时,log buffer 中的 redo log 会被刷新到磁盘。这可以通过参数 innodb_flush_log_at_trx_commit 来控制,具体细节将在后文提到。 - log buffer 空间不足
当 log buffer 中缓存的 redo log 占满了 log buffer 总容量的大约一半时,需要将这些日志刷新到磁盘。 - 事务日志缓冲区满
InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志刷新,将日志写入磁盘。 - Checkpoint(检查点)
InnoDB 定期执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并将相应的重做日志一同刷新,以确保数据的一致性。 - 后台刷新线程
InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。 - 正常关闭服务器
当 MySQL 服务器正常关闭时,redo log 会被刷新到磁盘,以确保所有未持久化的数据都被写入磁盘。 - 后台线程主动刷盘
当 redo log buffer 占用的空间接近 innodb_log_buffer_size 一半时,后台线程也会主动刷盘。
怎么将一条 SQL 加载到缓冲池和记录哪些日志的
- 准备更新:准备执行一条 SQL 更新语句。
- 查找数据:MySQL(InnoDB 引擎)会先在缓冲池(Buffer Pool)中查找这条数据。如果缓冲池中没有找到,则会从磁盘中查找,并将数据加载到缓冲池中。
- 保存原始记录:在加载到缓冲池的同时,会将这条数据的原始记录保存到 Undo 日志文件中。
- 执行更新:InnoDB 在缓冲池中执行更新操作,更新后的数据会记录在 Redo Log Buffer 中。
- 写入 Redo Log:MySQL 提交事务时,会将 Redo Log Buffer 中的数据写入到 Redo 日志文件中。
- 刷盘策略:刷磁盘可以通过 innodb_flush_log_at_trx_commit 参数来设置刷盘策略。
- 重启恢复:MySQL 宕机重启时,会将 Redo 日志恢复到缓冲池中。
如何优化mysql分页查询
-
最大id查询法
扫描意思呢?举个例子,我查询第一页的时候是limit 0,10 查询到的最后一条id是10,那么下一页的查询只需要查询id大于10的19条数据即可。 -
BETWEEN … AND
这种方式也只能适用于自增主键,并且id没有断裂,否者不推荐这种方式,我们发现使用BETWEEN AND的时候查询出来11条记录,也就是说BETWEEN AND包含了两边的边间条件。使用的时候需要特别注意一下。 -
limit id
这种查询方式就是先扫描4000010行,但是只取出id,然后再查询id大于这个值的前10条,这样虽然也是扫描了400多w行记录,由于id是主键,拥有者主键索引,所以查询 查询一个id的limit速度会快很多,我们可以对比一下一开始的limit 4000000,10,效率相差了3倍多。 -
延迟关联(个人推荐)
什么叫延迟关联,他让mysql扫描尽可能少的记录,获取到需要访问的记录后再根据关联列回到远表查询需要的所有列,这样听起来是不是很拗口,我们用sql来实现一下。 -
分表查询
mysql推荐一张表的存储不要超过500w数据,查询400w不到1秒对于一般的查询来说已经可以了,如果还要更快的话,我建议使用分表存储,分表又分两种情况,水平分表于垂直分表。
水平分表:
假如一张表的原始数据有1000w条数据,我可分三张表存储,一张表300的万,这样查询的时候压力就会小很多,并且效率也很高很多,那问题来了,如何这个水平水表如何实现呢?像可以借助mycat之类的中间件,阿里云也提供了数据库的分表技术,当然,你也可以自己手写分表,但是自己手写分表的时候需要注意id重复以及如何定义搭配当前id在那张表中,算法推荐使用hash值。
垂直分表:
假如张彪的记录有100w,按正常来说查询速度应该不会太慢,但是由于这张表的字段超多,而且还有很多text类型的字段,这个时候我们可以将占用空间比较小的字段分在一张表,占用空间比较大的字段分在另一张表,两张表一一关联,这样,查询的时候就会快很多了。
MySQL加锁的基本单位
加锁单位是 next-key lock ( 间隙锁 + 行锁)
原则1:加锁的基本单位是next-key lock。next-key lock是前开后闭区间。
原则2:查找过程中访问到的对象才会加锁。
原则3:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁。
原则4:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁。
原则5:唯一索引上的范围查询会访问到不满足条件的第一个值为止。(在 mysql 45 讲中有说明,丁老师认为这是一个 bug,且在 8
版本的时候已经修复,待会也会举例说明)
on 和 where 的区别
1、on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
2、where 条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
为什么不建议为区分度不高字段建立索引
- 索引维护的开销对于区分度不高的字段,虽然索引可以加快查询速度,但是维护索引所需的开销可能会超过索引带来的性能提升。因为当插入、更新或删除数据时,需要更新索引。
- 索引占用的空间索引占用了磁盘空间,而区分度不高的字段往往只包含少量不同的值。如果为这些字段建立索引,那么索引所占用的空间可能会超过字段本身的数据。这样就会浪费存储空间,并且可能导致磁盘的随机I/O增加。
- 不适用于某些查询对于区分度不高的字段,如果查询条件中包含该字段,使用索引可能并不高效。因为在这种情况下,使用全表扫描可能更加高效。
一条update更新语句的执行流程
核心组成部分
Redo Log、Undo Log、BinLog分别存的什么内容,分别是做什么用的? Redo Log
在引擎层实现,用来恢复数据的,保障已提交事务的持久化特性,记录的是物理级别的数据页(包括data page和undo page)做的修改
Undo Log 在引擎层实现的逻辑日志,用于数据回滚到之前状态,对于每个UPDATE语句,对应一条相反的UPDATE的undo log
BinLog 是Server实现的逻辑日志,用于复制和恢复数据,记录了所有的 DDL 和 DML
语句(除了数据查询语句select、show等)
WAL是什么,哪里用到了它? WAL全称为Write-Ahead Logging,预写日志系统。主要写undo log、redo
log、binlog这些用到了。真正使用WAL的原因是:磁盘的写操作是随机IO,比较耗性能,所以如果把每一次的更新操作都先写入log中,那么就成了顺序写操作,实际更新操作由后台线程再根据log异步写入
UndoLog会存储在哪些地方? 我们从图中也可以清晰的知道UndoLog在两个地方:Buffer Pool中的undo
page页,和磁盘中的表共享空间的Undo log
详解执行流程
Client客户端:
客户端通过tcp/ip发送一条sql语句到server层
Server层:
- 接收客户端过来的请求,进行权限验证
- 权限验证通过后,解析器会对SQL语句进行词法、语法分析等
- 经过验证解析的SQL语句会在优化器生成选择最优执行计划
- 然后执行器将会执行经过优化的SQL语句
对于Server层来说,它是不知道存储引擎的实现细节的,而是通过定义的API接口和存储引擎通信。可以理解为存储引擎是一个类,然后每个实例(InnoDB)都通过一个特殊的处理程序接口与MySQL服务器通信。
InnoDB引擎层:
- 调用存储引擎接口后,会先从Buffer Pool获取数据页,如果没有就从磁盘中读入Buffer Pool,然后判断更新前后的记录是否一样
- 开启事务,修改数据之前先记录undo log,写入Buffer Pool的undo page
- 开始更新page data中的记录,被修改的数据页称为脏页,修改会被记录到内存中的 redo log buffer中,再刷盘到磁盘的redo log文件,此时事务是 perpare阶段
- 这个时候更新就完成了,当时脏页不会立即写入磁盘,而是由后台线程完成,这里会用double write来保证脏页刷盘的可靠性
-还没结束呢,这时候可以通知Server层,可以正式提交数据了, 执行器记录binlog cache,事务提交时才会将该事务中的binglog刷新到磁盘中 - 这个时候Update语句完成了Buffer Pool中数据页的修改、undo日志、redo log缓存记录,以及记录binlog cache缓存
- commit阶段,这个阶段是将redo log中事务状态标记为commit
- 此时binlog和redo log都已经写入磁盘,如果触发了刷新脏页的操作,先把脏页copy到double write buffer里,Double Write Buffer 的内存数据刷到磁盘中的共享表空间 ibdata,再刷到数据磁盘上数据文件 ibd
什么是二阶段提交?
二阶段提交,顾名思义,会包含 2 个阶段:
prepare 阶段,协调器会询问所有执行器,是否可以提交事务
commit 阶段,协调器会通知执行器进行提交操作
update的执行阶段也用到了,比如:
- prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;
- commit阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit状态后,刷入到磁盘 redo log 文件)
MySQL执行一条Select语句是怎么运行的?
连接器:建立连接,管理连接、校验用户身份;
查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0已删除该模块;
解析 SQL:通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;
执行 SQL:执行 SQL 共有三个阶段:
- 预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列。
- 优化阶段:基于查询成本的考虑, 选择查询成本最小的执行计划;
- 执行阶段:根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端
为什么不用memory
-
这个缓存是本地缓存,如果有多台服务器,sql语句会随机发送给其中一台,无法保证相同的请求会发送给同一台,这样本地缓存命中率就比较低,本地缓存(即查询缓存)就没有什么用了
-
从查询缓存中取出结果或者将查询结果添加进查询缓存中,会带来额外性能消耗
-
当表的结构或内容发生变化时,使用这个表的缓存查询将不再有效,查询缓存值的相关条目将被清空。常见修改表结构和表内容的语句,如delete、insert、altertable很多。使用redis作为缓存将受这个影响很小,因为它是基于键值对保存缓存的,只有key对应的缓存内容发生变化,才会受到影响,其他key对应缓存内容发生变化对其几乎是没有影响的
添加链接描述
相关文章:
MySQL面试
文章目录 事务隔离级别需要解决的问题事务隔离级别 MySQL 中是如何实现事务隔离的实现可重复读 什么是存储引擎如何定位慢查询分析慢查询原因MySQL超大分页怎么处理索引失效什么时候建立唯一索引、前缀索引、联合索引?redolog与binlog是如何保证一致的redolog刷盘时…...
linux运维之shell编程
Shell 编程在系统运维中及其重要 1. Shell 编程概述 Shell 是一种命令行解释器,能够执行操作系统的命令。Shell 脚本是一个包含一系列 Shell 命令的文件,它可以被执行,以自动化和批量处理任务。常用的 Shell 类型包括 bash、sh、zsh 等。Shel…...
ssm 多数据源 注解版本
application.xml 配置如下 <!-- 使用 DruidDataSource 数据源 --><bean id"primaryDataSource" class"com.alibaba.druid.pool.DruidDataSource" init-method"init" destroy-method"close"></bean> <!-- 使用 数…...
Nginx核心配置详解
一、配置文件说明 nginx官方帮助文档:nginx documentation nginx的配置文件的组成部分: 主配置文件:nginx.conf子配置文件: include conf.d/*.conffastcgi, uwsgi,scgi 等协议相关的配置文件mime.types:…...
十六(AJAX3)、XMLHttpRequest、Promise、简易axios封装、案例天气预报、lodash-debounce防抖
1. XMLHttpRequest 1.1 XMLHttpRequest-基本使用 /* 定义:XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更…...
12.06 深度学习-预训练
# 使用更深的神经网络 经典神经网络 import torch import cv2 from torchvision.models import resnet18,ResNet18_Weights from torch import optim,nn from torch.utils.data import DataLoader from torchvision.datasets import CIFAR10 from torchvision import tr…...
【计算机网络】期末速成(2)
部分内容来源于网络,侵删~ 第五章 传输层 概述 传输层提供进程和进程之间的逻辑通信,靠**套接字Socket(主机IP地址,端口号)**找到应用进程。 传输层会对收到的报文进行差错检测。 比特流(物理层)-> 数据帧(数据链路层) -> 分组 / I…...
Python学习笔记10-作用域
作用域 定义:Python程序程序可以直接访问命名空间的正文区域 作用:决定了哪一部分区域可以访问哪个特定的名称 分类: 局部作用域(Local)闭包函数外的函数中(Enclosing)全局作用域࿰…...
Sui 主网升级至 V1.38.3
Sui 主网现已升级至 V1.38.3 版本,同时协议升级至 69 版本。请开发者及时关注并调整! 其他升级要点如下所示: 协议 #20199 在共识快速路径投票中设置允许的轮次数量。 节点(验证节点与全节点) #20238 为验证节点…...
linux的vdagent框架设计
1、vdagent Linux 的 spice 客户代理由两部分组成,一个系统范围的守护进程 spice-vdagentd 和一个 X11 会话代理 spice-vdagent,每个 X11 会话有一个。spice-vdagentd 通过 Sys-V initscript 或 systemd 单元启动。 如下图:spice-vdagent&a…...
vue3+elementPlus封装的一体表格
目录结构 源码 exportOptions.js export default reactive([{label: 导出本页,key: 1,},{label: 导出全部,key: 2,}, ])index.vue <template><div class"flex flex-justify-between flex-items-end"><div><el-button-group><slot name…...
判断是否 AGP7+ 的方法
如何判断? /*** 是否是AGP7.0.0及以上* param project* return*/static boolean isAGP7_0_0(Project project) {def androidComponents project.extensions.findByName("androidComponents")if (androidComponents && androidComponents.hasProp…...
使用 Streamlit +gpt-4o实现有界面的图片内容分析
在上一篇利用gpt-4o分析图像的基础上,进一步将基于 Python 的 Streamlit 库,结合 OpenAI 的 API,构建一个简洁易用的有界面图片内容分析应用。通过该应用,用户可以轻松浏览本地图片,并获取图片的详细描述。 调用gpt-4o…...
树莓集团是如何链接政、产、企、校四个板块的?
树莓集团作为数字影像行业的积极探索者与推动者,我们通过多维度、深层次的战略举措,将政、产、企、校四个关键板块紧密链接在一起,实现了资源的高效整合与协同发展,共同为数字影像产业的繁荣贡献力量。 与政府的深度合作政府在产业…...
Fyne ( go跨平台GUI )中文文档-Fyne总览(二)
本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16及更高版本,ide为goland2021.2??????? ?这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne…...
MySQL数据库(3)-SQL基础语言学习
1. DDL数据定义语言 1.1 什么是DDL DDL(Data Definition Language,数据定义语言)是SQL语言的一部分,用于定义和修改数据库结构。DDL主要包括以下三类语句: 1.CREATE:用于创建数据库对象,如数…...
下拉框根据sql数据回显
vue <a-form-item label"XXXX" :labelCol"labelCol" :wrapperCol"wrapperCol" required><a-select v-decorator"[disputeType, validatorRules.disputeType]" style"width: 200px" placeholder"请选择XXXX&q…...
电池销售系统
文末获取源码和万字论文,制作不易,感谢点赞支持。 摘 要 在当今信息爆炸的大时代,由于信息管理系统能够更有效便捷的完成信息的管理,越来越多的人及机构都已经引入和发展以信息管理系统为基础的信息化管理模式,随之信…...
四、镜像构建
四、镜像构建 从镜像大小上来说,一个比较小的镜像只有十几MB,而内核文件需要一百多MB,因此镜像里面是没有内核的,镜像是在被启动为容器后直接使用宿主机的内核,而镜像本身则只提供相应的rootfs,即系统正常…...
FastAPI 响应状态码:管理和自定义 HTTP Status Code
FastAPI 响应状态码:管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码,涵盖了常见的 HTTP 状态码分类,如信息响应(1xx)、成功状态(2xx)、客户端错误&a…...
C#设计模式--原型模式(Prototype Pattern)
原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过构造函数。这种方式可以提高性能,特别是在创建复杂对象时。C# 中可以通过实现 ICloneable 接口或自定义克隆方法来实现原型模式。 案例 1:文档编辑器…...
使用Goland对6.5840项目进行go build出现异常
使用Goland对6.5840项目进行go build出现异常 Lab地址: https://pdos.csail.mit.edu/6.824/labs/lab-mr.html项目地址: git://g.csail.mit.edu/6.5840-golabs-2024 6.5840运行环境: mac系统 goland git clone git://g.csail.mit.edu/6.5840-golabs-2024 6.5840 cd 6.5840/src…...
使用kibana实现es索引的数据映射和索引模版/组件模版
1 数据映射 数据映射官方链接 1.1 日期映射案例 1.创建一条索引。把索引中的字段生日映射为日期,并制定映射后的格式为年月日 PUT http://10.0.0.91:9200/zhiyong18-luckyboy-date {"mappings": {"properties": {"birthday": {&q…...
基于elementui的远程搜索下拉选择分页组件
在开发一个练手项目的时候,需要一个远程搜索的下拉选择组件; elementui自带的el-select支持远程搜索;但如果一次性查询的数据过多;会导致卡顿。故自己实现一个可分页的远程下拉选择组件 效果: 代码: <…...
每日一题 LCR 074. 合并区间
LCR 074. 合并区间 对遍历顺序注意一下就可以 class Solution { public:vector<vector<int>> merge(vector<vector<int>>& intervals) {int n intervals.size();sort(intervals.begin(),intervals.end());int idx 0;vector<vector<int&g…...
Flink SQL
Overview | Apache Flink FlinkSQL开发步骤 Concepts & Common API | Apache Flink 添加依赖: <dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-api-java-bridge_2.11</artifactId><version>…...
[免费]SpringBoot+Vue企业OA自动化办公管理系统【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue企业OA自动化办公管理系统,分享下哈。 项目视频演示 【免费】SpringBootVue企业OA自动化办公管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着信息技术在管理上越来越深入…...
Linux下编译安装METIS
本文记录Linux下编译安装METIS的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1 一、安装依赖 1.1 下载GKlib sudo apt-get install build-essential sudo apt-get install cmake 2.2 编译安装GKlib 下载GKlib代码, …...
LLM学习路径 - 渐进式构建知识体系
LLM学习路径 - 渐进式构建知识体系 文章目录 LLM学习路径 - 渐进式构建知识体系一、模型算法基础二、机器学习三、深度学习四、自然语言处理 (NLP)五、大规模语言模型 (LLM) References 一、模型算法基础 编程基础 Web 框架 深入学习 Gradio 与 Streamlit,理解其构…...
使用Unity脚本模拟绳索、布料(碰撞)
效果演示: 脚本如下: using System.Collections; using System.Collections.Generic; using UnityEngine;namespace PhysicsLab {public class RopeSolver : MonoBehaviour {public Transform ParticlePrefab;public int Count 3;public int Space 1;…...
Qt Chart 模块化封装曲线图
一 版本说明 二 完成示例 此文章包含:曲线轴设置,曲线切换,单条曲线显示,坐标轴。。。 三 曲线图UI创建 在UI界面拖放一个QWidget,然后在 Widget里面放一个 graphicsView 四 代码介绍 1 头文件 #include <QString> #in…...
【Linux】深入理解进程管理与fork系统调用的实现原理
【Linux】深入理解进程管理与fork系统调用的实现原理 进程基本概念描述进程-PCBtask_struct-PCB的一种task_ struct内容分类组织进程 查看进程通过系统调用获取进程标示符Fork 之后的代码共享1. **代码共享**2. **数据段不共享**总结 🌏个人博客主页:个人…...
C语言程序设计P5-2【应用函数进行程序设计 | 第二节】——知识要点:函数的参数及返回值和函数的调用及声明
知识要点:函数的参数及返回值和函数的调用及声明 视频: 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 1.求x的n次方的值也就是求n个x的乘积,可把x和n作为函数的形参,定义一个函数power来完成这个功能&am…...
【LeetCode】169.多数元素
题目连接: https://leetcode.cn/problems/majority-element/solutions/2362000/169-duo-shu-yuan-su-mo-er-tou-piao-qing-ledrh/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述: 思路一: 使用哈希表unordered_map记录每个元…...
0x0118消息 WM_SYSTIMER
0x0118消息就是WM_SYSTIMER 编辑框出现输入光标时,产生的消息. 0x0118 would be the undocumented WM_SYSTIMER, which appears to be used for caret blinks. 0x0118是一个undocument 消息, 微软没有记录。 但在一些库的源码中可以看到,比如ATL的库文…...
【Linux内核】Hello word程序
创建测试目录 mkdir -p ~/develop/kernel/hello-1 cd ~/develop/kernel/hello-1 创建MakeFile文件和内核.c文件 nano Makefile nano hello-1.c 编写内容 /* * hello-1.c - The simplest kernel module. */ #include <linux/module.h> /* Needed by all modules */…...
黑马redis
Redis的多IO线程只是用来处理网络请求的,对于读写操作命令Redis仍然使用单线程来处理 Redisson分布式锁实现15问 文章目录 主线程和IO线程是如何协作的Unix网络编程中的五种IO模型Linux世界一切皆文件生产上限制keys *、flushdb、flushall等危险命令keys * 遍历查询100W数据花…...
Robust Depth Enhancement via Polarization Prompt Fusion Tuning
paper:论文地址 code:github项目地址 今天给大家分享一篇2024CVPR上的文章,文章是用偏振做提示学习,做深度估计的。模型架构图如下 这篇博客不是讲这篇论文的内容,感兴趣的自己去看paper,主要是分享环境&…...
集合框架(3)Map
Map接口 现实生活与开发中,我们常会看到这样的一类集合:用户ID与账户信息、学生姓名与考试成绩、IP地址与主机名等,这种一一对应的关系,就称作映射。Java提供了专门的集合框架用来存储这种映射关系的对象,即java.util…...
Java反射机制—Class
Java反射机制是指在运行时动态地获取类的信息以及操作类的成员变量、方法和构造方法的能力。反射机制通过使用Class类来实现,Class类是Java中表示类的类。 通过反射机制,我们可以在运行时动态地创建对象、调用方法、访问属性等。反射机制提供了一种强大…...
C# 新语法中的字符串内插$和{}符号用法详解
自C#6.0开始提供一个新的语法糖,即"$" 符号,配合“{}”使用,它的作用除了是对String.format的简化,还可设置其格式模板,实现了对字符串的拼接优化。 语法格式: $"string {变量表达式}” 语…...
WordPress 独立站是否需要 CDN:深度解析及必要性分析
WordPress 是目前全球最流行的开源内容管理系统(CMS),其易用性和丰富的插件生态使得它成为搭建独立站的首选。然而,随着流量的增加以及用户体验的需求,网站的速度和可靠性变得至关重要。在这种情况下,CDN&a…...
dell电脑开不了机怎么回事?戴尔电脑无法开机解决方法
dell戴尔电脑开不了机,这是很多使用dell电脑用户常遇到的问题。这种故障情况是由多种原因引起,包括硬件故障、软件问题或电源问题等等。dell电脑开不了机怎么办呢?下面便为大家介绍一下相关解决修复方法,帮助用户解决戴尔电脑无法…...
如何解决 JavaScript 中的数组方法不生效?
在 JavaScript 中,数组方法是常用的工具,可以用来对数组进行操作。常见的数组方法包括 push(), pop(), shift(), unshift(), map(), filter(), reduce() 等。 然而,有时候我们会遇到数组方法“失效”或者不按预期工作的情况。这个问题的原因…...
道可云人工智能元宇宙每日资讯|全国工商联人工智能委员会成立会议在南京举办
道可云元宇宙每日简报(2024年12月5日)讯,今日元宇宙新鲜事有: 全国工商联人工智能委员会成立会议在南京举办 全国工商联人工智能委员会成立会议日前在江苏省南京市举办。中央统战部副部长、全国工商联党组书记沈莹出席会议并讲话…...
华为HCIP-Datacom H12-821H12-831 (12月最新题库)
备考HCIP-datacom的小伙伴注意啦 !!! 2024年下半年12月份最新(H12-821和H12-831)题库带解析,有需要的小伙伴移动至文章末 H12-821: H12-831: 1.BGP 邻居建立过程的状态存在以下几种:那么建立一个成功的连接所经历的状态机顺序是 A、3-1-2-5-4 B、1-3-5-2-4 C、…...
模型案例:| 手机识别模型!
导读 2023年以ChatGPT为代表的大语言模型横空出世,它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力,为人工智能技术的发展开辟了新的可能性。同时,人工智能技术正在进入各种应用领…...
AWS创建ec2实例并连接成功
aws创建ec2实例并连接 aws创建ec2并连接 1.ec2创建前准备 首先创建一个VPC隔离云资源并且有公有子网 2.创建EC2实例 1.启动新实例或者创建实例 2.创建实例名 3.选择AMI使用linux(HVM) 4.选择实例类型 5.创建密钥对下载到本地并填入密钥对名称 6.选择自己创建的VPC和公有子网…...
短视频矩阵系统开发|技术源代码部署
短视频矩阵系统通过多账号运营管理、多平台视频智能分发等功能,助力企业实现视频引流、粉丝沉淀和转化。 短视频矩阵系统是一种创新的营销工具,它整合了多账号管理、视频智能分发、数据可视化等多种功能,为企业在短视频领域的发展提供了强大…...
C# GDI绘制的小熊进度条
C# GDI小熊进度条 1、添加自定义控件winform using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;…...