Java面试——Mysql专题

MySQL中,如何定位慢查询?

开源工具

调试工具:Arthas
运维工具:Prometheus 、Skywalking

通过mysql自带的日志查询

默认是关闭的,因为开启会消耗性能,通过配置
slow_query_log=1
long_query_time=1

那这个SQL语句执行很慢, 如何分析呢?

如果一条sql执行很慢,我们可以通过mysql自带的执行计划explain来查看这条sql的执行情况。比如我们可以查看key和key_len字段来判断是否命中了索引。如果已经存在了索引,那么也可以判断是否存在索引失效的情况。第二个可以通过type关键字来查看是否有进一步的优化空间,是否存在全索引扫描或全盘扫描。第三个可以通过extra来查看是否出现了回表,如果出现了,那么可以通过添加索引或修改返回字段来修复。

了解过索引吗?(什么是索引)

索引在项目中还是比较常见的。它是帮助Mysql高效获取数据的数据结构,主要是用来提高数据检索的效率,降低数据库的IO成本。同时通过索引列对数据进行排序,降低了数据排序的成本,也降低了CPU的消耗。

索引的底层数据结构了解过嘛 ?

mysql实现索引主要使用两种数据结构:hash和B+树。
hash:它会把索引以hash的形式存储,因此当查找某一条记录时速度非常快。但是因为hash结构每一个键对应一个值,而且是散列分布,所以它并不支持范围查找和排序。
B+树:他会把索引以平衡树来组织,因为是树形结构,所以更适合用来处理排序,范围查找等功能。选择B+树的主要原因有:第一,阶数更多,路径更短。第二,磁盘读写代价B+树更低,因为B+树非叶子节点只存储指针,叶子节点只存储数据。第三,B+树便于扫库和区间查询,其叶子节点是一个双向链表。

B树和B+树的区别是什么呢?

第一,B树的叶子节点和非叶子节点都会存放数据,而B+树的数据都存放在叶子节点,所以在查询的时候,B+树的查找效率更加稳定。
第二,在范围查询的时候,B+树的效率更高,因为B+树的数据都存放在叶子节点,并且叶子节点是一个双向链表。

什么是聚簇索引什么是非聚簇索引 ?

聚簇索引指的是数据和索引存放在一起,在B+树的叶子节点存放的是整行数据,有且只有一个,一般主键作为聚簇索引。
非聚簇索引指的是数据和索引分开存储,B+树的叶节点保存的对应的主键,可以有多个,一般我们自己定义的索引是非聚簇索引。

知道什么是回表查询嘛 ?

        回表和聚簇索引与非聚簇索引有关,就是首先根据二级索引查询到对应主键,然后根据主键查询到聚簇索引中整行数据。

知道什么叫覆盖索引嘛 ?

覆盖索引是指在select查询语句中使用了索引,并且在需要返回的列中,在索引中能够全部找到。
如果我们在使用id查询时,走的是聚集索引,一次索引扫描,直接返回数据,性能高。
如果使用二级索引查询数据,在需要返回的列中没有创建索引,那么可能会导致回表查询。所以我们尽量避免使用select *,尽量在返回的数据中都包含添加索引的字段。

MYSQL超大分页怎么处理 ?

首先超大分页是在数据量特别大时,使用limit分页查询,并且需要对数据进行排序,这样会导致效率很低。那么我们可以使用覆盖索引和子查询来解决。<br />先分页查询数据的id字段,因为走的覆盖索引,所以效率很高,然后使用子查询来过滤,只查询这个id表里的数据就可以了。

索引创建原则有哪些?

  • 前提:表中数据超过10万以上
  • 添加索引的字段是查询比较频繁的字段,一般作为查询条件,排序字段或者分组的字段。
  • 通常创建索引的时候都是使用复合索引来创建,一条sql的返回值,尽量使用覆盖索引,如果字段区分度不高的话,我们会把它放在组合索引后面的字段。
  • 如果一个字段的内容较长,我们会考虑使用前缀索引来使用
  • 并不是所有的字段都要添加索引,索引的数量也要控制,因为添加索引也会导致新增改的速度变慢。

什么情况下索引会失效?

  • 没有遵循最左匹配法则
  • 条件中有or
  • 索引字段有null
  • 模糊查询以%开头
  • 在添加索引的字段上进行了运算操作或者类型转换
  • 复合索引中间使用了范围查询,右边的条件索引也会失效

事务的特性是什么?

ACID,分别是原子性,一致性,隔离性,持久性

  • 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成。事务执行过程中发生错误,会被回滚到事务开始之前的状态。
  • 一致性:事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。
  • 隔离性:可以通过隔离级别,设置并发事务的影响程度。
  • 持久性:事务执行成功后,该事务对数据库的更改时持久保存在数据库中的,不会被回滚。

并发事务带来哪些问题?怎么解决这些问题呢?MySQL的默认隔离级别是?

第一是脏读,当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,并且这个数据是没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
第二是不可重复读,比如一个事务多次读取同一数据,在这个事务还没有结束时,另一个事务也访问该数据,那么在第一个事务两次读取的数据之间,由于第二个事务的修改导致两次读取到的数据不一样。
第三是幻读,幻读与不可重复读类似。它发生在第一个事务读取了几行数据,然后第二个事务插入了一些数据,在随后的查询中,第一个事务发现多了一些原本不存在的数据,就好像发生了幻觉一样,所以叫幻读。
解决方案是对事务进行隔离,mysql支持四种隔离级别,分别有:
第一个是读未提交,它解决不了所有的问题,所有项目中一般不使用。
第二个是读已提交,它可以解决脏读的问题,但是解决不了不可重复读和幻读。
第三个是可重复读,它可以解决脏读和不可重复读,但是解决不了幻读,它也是mysql的默认隔离级别。
第四个是串行化,它可以解决所有的问题,但是由于是让事务串行执行,性能较低,所以我们一般使用可重复读。

undo log和redo log的区别

好的,其中redo log日志记录的是数据页的物理变化,服务宕机可用来恢复数据,而undo log记录的是逻辑日志,当事务回滚时,通过逆操作恢复原来的数据。比如我们删除一条数据的时候,就会在undo log日志文件中新增一条delete语句,如果发生回滚就执行逆操作。
redo log保证了事务的持久性,undo log保证了事务的原子性和一致性。

事务中的隔离性是如何保证的呢?(解释一下MVCC)

image.png

MySQL主从同步原理

image.png

sql优化的经验

image.png

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值