JAVA面试专题-MySQL

全局锁

对这个数据库实例加锁,加锁后整个实例处于只读状态,DDL和DML阻塞,DQL可以

表级锁

每次操作锁住整张表

表锁

表共享读锁(read lock):不阻塞其他客户端的读,但会阻塞写

表独占写锁(write lock):阻塞其他客户端的读写

元数据锁(meta data lock MDL)

如果某一个表存在活动事务,不可以对元数据写入操作,当对一张表进行增删改查的时候,加读锁,当对表结构进行变更操作的时候,加写锁

read和write兼容,和exclusive不兼容

意向锁

意向共享锁(IS):与read兼容,和write排斥

意向排他锁(IX):与read和write互斥,意向锁之间不会互斥

行级锁

每次操作锁住对应的行数据,发生锁冲突的概率最低,并发度最高

行锁

锁定单行记录,防止其他事务对此进行update和delete,RC和RR都支持

共享锁S:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁

排他锁X:运行获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁

  1. 针对唯一索引进行检索时,对已存在的记录进行等值匹配,将会自动优化为行锁

  2. InnoDB的行锁针对索引加的锁,不通过索引条件检索数据,将会升级为表锁

间隙锁

间隙锁:锁定索引记录间隙,确保索引记录间隙不变,防止其他事物在这个间隙进行insert,产生幻读,RR支持

临键锁

临键锁:行锁和间隙锁组合,同时锁住数据和数据前面的间隙,RR支持

SQL优化

如何定位慢查询

常见的慢查询有聚合查询,多表查询,表数据量过大查询,深度分页查询

方案一:开源工具 Skywalking

方案二:MySQL慢查询日志,在MySQL的配置文件开启开关和时间

如何定位慢查询

使用explain或者desc获取MySQL语句信息

possible_keys 当前sql可能会用到的索引

key 当前sql实际命中的索引

key_len 索引占用的大小

extra 额外的优化建议 using where/index 使用索引并且没回表查询 using index condition 使用索引但是回表查询

type system:查询系统中的表;const:主键查询; eq_ref:主键索引查询或唯一索引查询

ref:索引查询;range:范围查询;index:索引树扫描;all:全盘扫描

MySQL支持的存储引擎有哪些,什么区别?

InnoDB

特点:事务外键行级锁

索引

索引:帮助MySQL高效获取数据的数据结构,提高数据检索效率,降低数据库IO成本,通过索引列对数据进行排序,降低数据排序成本,降低了cpu的消耗。

B树与B+树对比:

磁盘读写代价b+树更低:非叶子节点只存储指针,只有叶子结点存储数据

查询效率B+树更稳定:阶数更多,路径更短

B+树便于扫库和区间查询:叶子结点是一个双向链表

聚簇索引和非聚簇索引

聚簇索引(聚集索引):将数据存储与索引放到了一块,索引结构的叶子结点保存了行数据,有且仅有一个。

非聚簇索引(非聚集索引,二级索引):将数据与索引分开存储,索引结构的叶子结点关联对应的主键,可以存在多个

聚簇索引选取规则:

存在主键,主键索引就是聚簇索引

不存在主键,第一个唯一索引就是聚簇索引

都没有,InnoDB会自动生成一个rowid作为隐藏的聚簇索引

回表查询

回表查询:通过二级索引找到对应的主键值,到聚集索引中查找整行数据,就是回表

覆盖索引

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

MySQL超大分页处理

数据量较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低

优化思路:覆盖索引+子查询:先分页查询id字段,再用子查询来过滤

索引创建原则

  1. 数据量较大,且查询比较频繁的表

  2. 常作为条件查询、排序、分组的字段

  3. 尽量使用联合索引,避免回表

  4. 要控制索引的数量

  5. 尽量选择区分度高的列作为索引

  6. 如果所以不能存储null,要用非空约束

  7. 字段名称过长可以使用前缀

索引失效

  1. 违反最左前缀法则:如果索引了多列,要遵守最左前缀法则:查询从索引的最左前列开始,并且不能跳过索引中的列,匹配最左前缀法则,走索引。如果符合最左法则,但是出现跳跃某一列,只有最左列索引生效

  2. 如果一个索引使用了范围查询,其右面的索引不生效

  3. 在索引列上运算操作,索引将失效

  4. 字符串不加单引号,索引失效

  5. 模糊查询如果有头部匹配,索引失效

SQL优化经验

表设计优化

设置合适的数值,根据实际情况选择

SQL语句优化

避免使用select *

SQL语句要避免索引失效

尽量使用union all

避免在where字句中进行表达式操作

尽量使用inner join,内连接会对两个表优化,优先把小表放在外面

主从复制,读写分离

事务相关

事务特性ACID

原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败

一致性:事务完成时,必须所有数据保持一致状态

隔离性:数据库提供隔离机制,保证事务在不受外部并发操作影响的独立环境中运行

持久性:事务一旦提交或者回滚,对数据库的数据改变就是永久的

并发事务问题

undo log 和 redo log

缓冲池不断向数据页中同步数据,要处理脏写问题,不断向redo log(重做日志) buffer中写数据,然后同步到磁盘中的redo log file中,但是如果没有异常,依旧是buffer pool 与 数据页进行交换数据。

回滚日志undo log:用于记录数据被修改前的信息,提供回滚和mvcc,redo log记录物理日志,undo log记录逻辑日志。undolog 可以实现 事务的一致性和与原子性

对于隔离性:可以使用排他锁或者mvcc

MVCC(Multi-Version Concurrency Control)多版本并发控制

维护一个数据的多个版本,使得读写操作没有冲突

隐藏字段:

db_trx_id:最近修改的事务id,记录插入这条记录或者最后一次修改该记录的事务id

db_roll_ptr:回滚指针,指向这条记录的上一个版本,配合undo log

db_row_id:如果没有主键,将会生产该隐藏字段

undo log:

回滚日志,存储老版本数据

版本链:多个事务并行操作某一行记录,记录不同事务修改数据的版本,荣光rool ptr形成链表

readView解决实物查询选择版本问题

根据readView的匹配规则和当前的一些事务id判断访问哪个版本的数据

不同的隔离级别快照读是不一样的,最终的访问结果不一样:

RC:每一次执行快照读时生成readview

RR:仅事务第一次执行快照读时生产readview,后续复用

主从同步

核心是二进制日志binlog

  1. master提交事务时,会将事务变更记录在二进制文件binlog中

  2. 从库读取binlog,写到从库的中继日志relay log中

  3. slave重做中继日志中的时间,改变自己的数据

分库分表

垂直拆分

水平拆分

相关推荐
IU宝2 分钟前
C/C++内存管理
java·c语言·c++
瓜牛_gn3 分钟前
依赖注入注解
java·后端·spring
hakesashou4 分钟前
Python中常用的函数介绍
java·网络·python
打鱼又晒网8 分钟前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
佚先森13 分钟前
2024ARM网络验证 支持一键云注入引流弹窗注册机 一键脱壳APP加固搭建程序源码及教程
java·html
古月居GYH26 分钟前
在C++上实现反射用法
java·开发语言·c++
tatasix1 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
ifanatic1 小时前
[面试]-golang基础面试题总结
面试·职场和发展·golang