MySQL面试题

目录

MySQL的隔离级别有哪些?

MySQL复制原理是什么?

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

索引的基本原理

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

MySQL锁的类型有哪些?

MySQL为什么需要主从同步?

MySQL执行计划怎么看?

简述mysql中索引类型有哪些,以及对数据库的性能的影响?

什么是MySQL的主从复制?

怎么处理MySQL的慢查询?

索引的设计原则有哪些?


MySQL的隔离级别有哪些?

MySQL定义了四种隔离级别,用于限定事务内外哪些改变是可见的,哪些改变是不可见的。
低级别的隔离一般支持效率更高的并发处理,并且拥有更低的系统开销,但数据不安全。隔离级别越高数据越安全,但并行执行效率越低。

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

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

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

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

1.脏读
脏读是指一个事务读取了未提交事务执行过程中的数据。当一个事务的操作正在多次修改数据,而在事务还未提交的时候,另外一个并发事务来读取了数据,就会导致读取到的数据并非是最终持久化之后的数据,这个数据就是脏读的数据。

2.不可重复读
不可重复读是指对于数据库中的某个数据,一个事务执行过程中多次查询返回不同查询结果,这就是在事务执行过程中,数据被其他事务提交修改了。
不可重复读同脏读的区别在于,脏读是一个事务读取了另一未完成的事务执行过程中的数据,而不可重复读是一个事务执行过程中,另一事务提交并修改了当前事务正在读取的数据。

3.虚读(幻读)
幻读是事务非独立执行时发生的一种现象,例如事务T1批量对一个表中某一列列值为1的数据修改为2的变更,但是在这时,事务T2对这张表插入了一条列值为1的数据,并完成提交。此时,如果事务T1查看刚刚完成操作的数据,发现还有一条列值为1的数据没有进行修改,而这条数据其实是T2刚刚提交插入的,这就是幻读。

幻读和不可重复读都是读取了另一条已经提交的事务(这点同脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体 (比如数据的个数)。

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--master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启b
nlog二进制日志
功能;通常为了数据安全考虑, slave也开启binlog功能)。
2--slave开启两个线程:lO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
3--Mysql复制至少需要两个MysqlI的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
4--Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)1
5--master和slave两节点间时间需同步

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

mysql的索引类型跟存储引擎是相关的,innodb存储引擎数据文件跟索引文件全部放在ibd文件中,而myisam的数据文件放在myd文件中,索引放在myi文件中,其实区分聚族索引和非聚簇索引非常简单,只要判断数据跟索引是否存储在一起就可以了
innodb存储引擎在进行数据插入的时候,数据必须要跟索引放在一起,如果有主键就使用主键,没有主键就使用唯一键,没有唯一键就使用6字节的rowid,因此跟数据绑定在一起的就是聚簇索引,而为了避免数据几余存储,其他的索引的叶子节点中存储的都是聚簇索引的key值,因此innodb中既有聚簇索引也有非聚簇索引,而myisam中只有非聚簇索引。

索引的基本原理

1、为什么要有索引?

一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。
2、什么是索引?
索引在MySQL中也叫是一种”键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查.

3、索引的原理
索引的目的在于提高查询效率,与我们查阅图书所用的目录是一个道理: 先定位到章,然后定位到该章下的一个小节,然后找到页数。相似的例子还有: 查字典,查火车车次,飞机航班等
本质都是: 通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据
数据库也是一样,但显然要复杂的多,因为不仅面临着等值查询,还有范围查询(<、between、in)、模糊查询(like)、并集查询(or)等等。数据库应该选择怎么样的方式来应对所有的问题呢? 我们回想字典的例子,能不能把数据分成段,然后分段查询呢?最简单的如果1000条数据,1到100分成第一段,101到200分成第二段,201到300分成第三段...这样查第250条数据,只要找第三段就可以了,一下子去除了90%的无效数据。但如果是1千万的记录呢,分成几段比较好?按照搜索树的模型,其平均复杂度是lgN,具有不错的查询性能。但这里我们忽略了一个关键的问题,复杂度模型是基于每次相同的操作成本来考虑的。而数据库实现比较复杂,一方面数据是保存在磁盘上的,另外一方面为了提高性能,每次又可以把部分数据读入内存来计算,因为我们知道访问磁盘的成本大概是访问内存的+万倍左右,所以简单的搜索树难以满足复杂的应用场景

4、索引的数据结构

MySQL主要用到两种结构: B+ Tree索和Hash索引Inodb存储引擎 默认是 B+Tree索引
Memory 存储引擎 默认 Hash索引;MySQL中,只有Memorv(Memorv表只存在内存中,断电会消失,适用于临时表)存储引警显示支持Hash索引是Memory表的默认索引类型,尽管Memorv表也可以使用B+Tree索引。Hash索引把数据以hash形式组织起来因此当查找某一条记录的时候,速度非常快。但是因为hash结构,每个键只对应一个值,而且是散列的方式分布。所以它并不支持范围查找和排序等功能。
B+Tree是mysql使用最频繁的一个索引数据结构,是InnoDB和MyISAM存储引擎模式的索引类型。相对Hash索引,B+Tree在查找单条记录的速度比不上Hash索引,但是因为更适合排序等操作,所以它更受欢迎。毕竟不可能只对数据库进行单条记录的操作。
对比:
hash类型的索引: 查询单条快,范围查询慢
btree类型的索引: b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它)

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

索引的数据结构和具体存储引擎的实现有关,mysql中使用较多的索引有hash索引,B+树索引,innodb的索引实现为B+树,memory存储引擎为hash索引。
B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的二节点间有指针相关连接,在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。因为,B+树索引被广泛应用于数据库、文件系统等场景。
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值,前提是键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,知道找到对应的数据如果是范围查询检索,这时候哈徐索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索
哈希所有也没办法利用索引完成排序,以及like这样的部分模糊查询哈希索引也不支持多列联合索引的最左匹配规则
B+树索引的关键字检索效率比较平均,不像B树那样波动大,在有大量重复键值情况下,哈希索引的效率也是极低的,因此存在哈希碰撞问题。

MySQL锁的类型有哪些?

基于锁的属性分类:共享锁(读锁)、排他锁(写锁)。
基于锁的粒度分类:行级锁((innodb )、表级锁( innodb、myisam)、页级锁( innodb引擎
、记录锁、间隙锁、临键锁。

基于锁的状态分类:意向共享锁、意向排它锁。
共享锁(share lock):共享锁又称读锁,简称S锁;当一个事务为数据加上读锁之后,其他事务只能对该数据加读锁,而不能对数据加写锁,直到所有的读锁释放之后其他事务才能对其进行加持写锁。共享锁的特性主要是为了支持并发的读取数据,读取数据的时候不支持修改,避免出现重复读的问题。
排他锁(exclusive lock)︰排他锁又称写锁,简称×锁;当一个事务为数据加上写锁时,其他请求将不能再为数据加任何锁,直到该锁释放之后,其他事务才能对数据进行加锁。排他锁的目的是在数据修改时候,不允许其他人同时修改,也不允许其他人读取,避免了出现脏数据和脏读的问题。
表锁(table lock):表锁是指上锁的时候锁住的是整个表,当下一个事务访问该表的时候,必须等前一个事务释放了锁才能进行对表进行访问;特点:粒度大,加锁简单,容易冲突;
行锁:行锁是指上锁的时候锁住的是表的某一行或多行记录,其他事务访问同一张表时,只有被锁住的记录不能访问,其他的记录可正常访问,特点:粒度小,加锁比表锁麻烦,不容易冲突,相比表锁支持的并发要高
记录锁(Record lock):记录锁也属于行锁中的一种,只不过记录锁的范围只是表中的某一条记录
记录锁是说事务在加锁后锁住的只是表的某一条记录,加了记录锁之后数据可以避免数据在查询的时候被修改的重复读问题,也避免了在修改的事务未提交前被其他事务读取的脏读问题。

页锁:页级锁是MysQL中锁定粒度介于行级锁和表级锁中间的一种锁.表级锁速度快,但冲突多
行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。特点:开销和加锁时间界于表锁和行锁之间,会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
间隙锁:是属于行锁的一种,间隙锁是在事务加锁后其锁住的是表记录的某一个区间,当表的相邻ID之间出现空隙则会形成一个区间,遵循左开右闭原则。范围查询并且查询未命中记录,查询条件必须命中索引、间隙锁只会出现在REPEATABLE_READ(重复读)的事务级别中。
临键锁(NextRey lock):也属于行锁的一种,并且它是INNODB的行锁默认算法,总结来说它就是记录锁和间隙锁的组合,临键锁会把查询出来的记录锁住,同时也会把该范围查询内的所有间隙空间也会锁住,再之它会把相邻的下一个区间也会锁住。

MySQL为什么需要主从同步?

1、在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务
那么就很影响
运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
2、做数据的热备
3、架构的扩展。业务量越来越大,V/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘IO访问的频率,提高单个机器的I/O性能。
 

MySQL执行计划怎么看?

id 

select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序id号分为三种情况:
1、如果id相同,那么执行顺序从上到下

2、如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

3、id相同和不同的,同时存在:相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行
select_type
主要用来分辨查询的类型,是普通查询还是联合查询还是子查询
type
type显示的是访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描
直接暴力的
遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery>range > index > ALL 1
一般情况下,得保证查询至少达到range级别,最好能达到ref


简述mysql中索引类型有哪些,以及对数据库的性能的影响?

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

唯一索引:可以保证数据记录的唯一性
主键索引:是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字primary key来创建
联合索引:索引可以覆盖多个数据列
全文索引:通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术
索引可以极大地提高数据的查询速度
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能
但是会降低插入、删除、更新表的速度,因为在执行这些写操作的时候,还要操作索引文件
索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要简历聚簇索引,那么需要的空间就会更大,如果非聚簇索引很多,一旦聚簇索引改变,那么所有非聚簇索引都会跟着变


什么是MySQL的主从复制?

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


怎么处理MySQL的慢查询?


1、开启慢查询日志,准确定位到哪个sql语句出现了问题
2、分析sql语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写
3、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引
4、如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。

索引的设计原则有哪些?

在进行索引设计的时候,应该保证索引字段占用的空间越小越好,这只是一个大的方向,还有一些细节点需要注意下:
1、适合索引的列是出现在where字句中的列,或者连接子句中指定的列

2、基数较小的表,索引效果差,没必要创建索引
3、在选择索引列的时候,越短越好,可以指定某些列的一部分,没必要用全部字段的值4、不要给表中的每一个字段都创建索引,并不是索引越多越好
5、定义有外键的数据列一定要创建索引
6、更新频繁的字段不要有索引
7、创建索引的列不要过多,可以创建组合索引,但是组合索引的列的个数不建议太多“

8、大文本、大对象不要创建索引
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龍弟-idea

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

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

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

打赏作者

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

抵扣说明:

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

余额充值