MySQL面试题总结

MySQL面试题

MySQL的隔离级别有哪些?


MySQL定义了四种隔离级别,包括一些具体规则,用于限定事务内外哪些改变是可见的,哪些改变时不可见的。低级别的隔离一般支持更高的并发处理,并且拥有更低的系统开销。

READ UNCOMMITTED 读取未提交内容

在这个隔离级别,所有事物都可以“看到”未提交事物的执行结果。在这种级别上,可能会产生很多问题,除非用户真的知道自己在做什么,并有很好的理由选择这样做。本隔离级别很少用于实际应用,因为他的性能也不比其他性能好多少,而别的级别还有其他更多的嗯有点。读取未提交数据,也称为“脏读”

READ COMMIITED 读取提交内容

大多数数据库系统的默认隔离级别(但是不是MySQL的默认隔离级别),满足了隔离的早先简单定义:一个事物开始时,只能“看见”已经提交事物所做的改变,一个事物从开始到提交前,所做的任何数据改变都是不可见的,除非已经提交。这种隔离级别也支持所谓的“不可重复读”。这意味着用户运行同一个语句两次,看到的结果是不同的。

REPEATABLE READ 可重复读

MySQL数据库默认的隔离级别。该级别解决了READ UNCOMMITTED隔离级别所导致的问题。他保证同一事务的多个实例在并发读取事物时,会“看到同样的”数据行。不过,这会导致另一个棘手问题“幻读”。InnoDB和Falcon存储引擎通过多版本并发控制机制解决了幻读问题。

SERIALIZABLE 可串行化

该级别是最高级别的隔离级。它通过强制事物排序,使之不可能相互冲突,从而解决幻读问题。总而言之,SERIALIZABLE是在每个读的数据行上加锁。在这个级别,可能导致大量的超市Timeout和锁竞争Lock Contention现象,实际应用中很少使用到这个级别,但如果用户的应用为了数据地稳定性,需要强制减少并发的话,也可以选择这种隔离级。

总结:

事务有特性称为隔离性,多事务操作之间不会产生影响,不考虑隔离性产生很多问题

有三个读问题:脏读、不可重复读、虚(幻)读

脏读:一个未提交事务读取到另一个未提交事务的数据

不可重复读: 一个未提交事务读取到另一提交事务修改数据

幻读: 一个未提交事务读到另一提交事务添加数据

隔离级别

脏读不可重复读幻读
READ UNCOMMITTED(读未提交)
READ COMMITTED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行化)

MySQL复制原理是什么?


(1)master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;

(2)slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件

(3)同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

也就是说:

  • 从库会生成两个线程,一个I/O线程,一个SQL线程
  • I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中
  • 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
  • SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

具体步骤:

1、从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件(user、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 postition号); start slave

2、从库的IO线程和主库的dump线程建立连接。

3、从库根据change master to 语句提供的file名和postition号,IO线程向主库发起binlog的请求。

4、主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。

5、从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中。

6、从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用的relay会自动被清理purge

MySQL聚簇和非聚簇索引的区别是什么?


​ mysql的索引类型跟存储引擎室相关的,innodb存储引擎数据文件跟索引文件全部放在ibd文件中,而myiam的数据文件放在myd文件中,索引放在myi文件中,其实区别分聚簇索引和非聚簇索引非常简单,只要判断数据跟索引是否存储一起就可以了。

​ innodb存储殷勤在进行数据插入的时候,数据必须要跟索引放在一起,如果有主键就使用主键,没有主键就使用唯一键,没有唯一键就是用6字节的rowid,因此跟数据绑定在一起的就是聚簇索引,而为了避免数据冗余存储,其他的索引的叶子节点中存储的都是聚簇索引的key值,因此innodb中既有聚簇索引也有非聚簇索引,而myisam中只有非聚簇索引。

MySQL索引的基本原理


1、为什么要有索引?

一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然室重中之重,说起加速查询,就不得不提到索引。

2、什么是索引?

索引在MySQL中也叫是一种“键”,是存储殷勤用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大的时,索引对于性能的影响愈发重要。

索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。

索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。

3、索引的原理

4、索引的数据结构

MySQL主要用到两种结构:B+ Tree索引和Hash索引

Inodb存储引擎 默认是B+Tree索引

Memory 存储引擎 默认是 Hash索引;

MySQL中,只有Memory(Memory表中只存在内容中,断电会消息,适用于临时表)存储引擎显示支持Hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B+Tree索引。Hash索引把数据以hash形式组织起来,因此当查找某一条记录的时候,速度非常快。但是因为hash结构,每个键只对应一个值,而且是散列的方式分布。所以他并不支持范围查找和排序等功能。

B+Tree是mysql使用最频繁的一个索引数据结构,是InnoDB是MyISAM存储引擎模式的索引类型。相对Hash索引,B+Tree在查找单条记录的速度比不上Hash索引,但是因为更适合排序等操作,所以它更受欢迎。毕竟不可能支队数据库进行单条记录的操作。

hash类型的索引:查询单条快,范围查询慢

btree类型的索引:b+树,层数越多,数据指数级增长

MySQL索引结构有哪些,各自的优劣是什么?


索引的数据结构和具体存储引擎的实现有关,mysql中使用较多的索引有hash索引,B+树索引,innodb的索引实现为B+树,memory存储引擎为hash索引。

B+树是一个平衡的多叉树,从根节点刀每个叶子节点的高度差值不超过1,而且同层级的二节点间有指针相关连接,在B+树上的常规检索,从根节点刀叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。因此,B+树索引被广泛应用于数据库、文件系统等场景。

哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。

如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值,前提是键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,知道对应的数据。

如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索

哈希索引也没有办法利用索引完成排序,以及like这样的部分模糊查询

哈希索引也不支持多列联合索引的最左匹配规则

B+树索引的关键字检索效率比较平均,不像B树那样波动大,在有大量重复键值情况下,哈希索引的效率也是极低的,因此存在哈希碰撞问题。

MySQL锁的类型有哪些?


==基于锁的属性分类:==共享锁、排他锁

==基于锁的粒度分类:==行级锁(innodb)、表级锁(innodb、myisam)、页级锁(innodb)、记录锁、间隙锁、临键锁

基于锁的状态分类:意向共享锁、意向排它锁。

MySQL为什么需要主从同步?


1、 在业务复杂的系统中,有这么一个场景,有一句SQL语句需要锁表,导致暂时不能使用读的服务,那么就影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的场景,通过读从库也可以保证业务的正常运作。

2、 做数据的热备

3、 架构的扩展。业务量越来越大,I/O访问平吕过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。

MySQL执行计划怎么看?


​ 在企业的应用场景中,为了知道优化SQL语句的执行,需要查看SQL语句的具体执行过程,以加快SQL语句的执行效率。

​ 可以使用explain+SQL语句来模拟优化器执行SQL查询语句,从而知道mysql是如何处理sql语句的。

1、执行计划包含的信息

ColumnMeaning
idThe SELECT identifiter
select_typeThe SELECT type
tableThe table for output row
partitonsThe matching partitions
typeThe join type
possible_keysThe possible indexes to choose
keyThe index actually chosen
key_lenThe length of the chosen key
refThe columns compared to the index
rowsEstimate of rows to be examined
filteredPercentage of rows filtered by table condition
extraAdditional information

id

select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序

id号分为三种情况:

  1. 如果id相同,那么执行顺序从上到下

    explain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sal between sg.losal and sg.hisal;
    
  2. 如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

    explain select * from emp e where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');
    
  3. id相同和不同的,同时存在;相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行

    explain select * from emp e join dept d on e.deptno = d.deptno join salgarde sg on e.sal between sg.losal and sg.hisal where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');
    

select_type

主要用来分辨查询的类型,是普通查询还是联合查询还是子查询

type

type显示的访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描,直接暴力的遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般情况下,得保证查询至少达到range级别,最好能达到ref

MySQL索引类型有哪些,对数据库的性能的影响?


普通索引:允许被索引的数据列包含重复的值

唯一索引:可以保证数据记录的唯一性

主键索引:是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字primary key来创建

联合索引:索引可以覆盖多个数据列

全文索引:通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术

索引可以极大地提升数据的查询速度

通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能

但会降低插入、删除、更新表的速度,因为在执行这些写操作的时候,还要操作索引文件

索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要遍历聚簇索引,那么需要的空间就会更大,如果非聚簇索引很多,一旦聚簇索引改变,那么所有非聚簇索引都有跟着变

MySQL的主从复制是什么?


​ MySQL主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL默认来用异步复制方式,这种从节点不用一直访问主服务器来更新自己的数据,数据的更新可以从远程连接上进行,从节点可以复制主数据库中的所有数据或特定的数据库,或者特定的表。

MySQL的慢查询怎么处理


1、开启慢查询日志,准确定位到哪个sql语句出现了问题

2、分析sql语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写

3、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引

4、如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。

MySQL索引的设计原则有哪些?


在进行索引设计的时候,应该保证索引字段占用的空间越小越好,这只是一个大的方向,还有一些细节点需要注意下:

  1. 适合索引的列是出现在where子句中的列,或者连接子句中指定的列
  2. 基数较小的表,索引效果差,没必要的创建索引
  3. 在选择索引列的时候,越短越好,可以指定某些列的一部分,没必要用全部字段的值
  4. 不要给表中的每一个字段都创建索引,并不是索引越多越好
  5. 定义有外键的数据列一定要创建索引
  6. 更新频繁的字段不要有索引
  7. 创建索引的列不要过多,可以创建组合索引,但是组合索引的列的个数不建议太多
  8. 大文本、大对象不要创建索引
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J.T.L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值