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重做中继日志中的时间,改变自己的数据

分库分表

垂直拆分

水平拆分

相关推荐
·薯条大王1 小时前
MySQL联合查询
数据库·mysql
战族狼魂2 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
xyliiiiiL3 小时前
ZGC初步了解
java·jvm·算法
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
hycccccch4 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
天天向上杰5 小时前
面基JavaEE银行金融业务逻辑层处理金融数据类型BigDecimal
java·bigdecimal
请来次降维打击!!!5 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
用键盘当武器的秋刀鱼5 小时前
springBoot统一响应类型3.5.1版本
java·spring boot·后端
Alo3655 小时前
面试考点复盘(二)
面试
嘤国大力士6 小时前
C++11&QT复习 (七)
java·c++·qt