其他资料
每日速记10道java面试题13-MySQL篇-CSDN博客
目录
[脏读(Dirty Read)](#脏读(Dirty Read))
[不可重复读(Non-repeatable Read)](#不可重复读(Non-repeatable Read))
[幻读(Phantom Read)](#幻读(Phantom Read))
3.MySQL默认的事务隔离级别是什么?为什么选择这个级别?
[4. MySQL 的乐观锁和悲观锁是什么?](#4. MySQL 的乐观锁和悲观锁是什么?)
[6.如何使用 MySQL 的 EXPLAIN 语句进行查询分析?](#6.如何使用 MySQL 的 EXPLAIN 语句进行查询分析?)
[7.MySQL中 count(*)、count(1)和 count(字段名) 有什么区别?](#7.MySQL中 count(*)、count(1)和 count(字段名) 有什么区别?)
[8.MySQL 中 int(11) 的 11 表示什么?](#8.MySQL 中 int(11) 的 11 表示什么?)
[9.MySQL中 varchar 和 char 有什么区别?](#9.MySQL中 varchar 和 char 有什么区别?)
[10. MySQL如何对SQL语句进行调优?](#10. MySQL如何对SQL语句进行调优?)
1.如果MySQL中没有MVCC,会有什么影响?
如果没有mvcc,并发情况下想保持数据的一致性,无论读写都要对数据进行加锁(串行化隔离级别),大大影响了数据读写的性能。
多个事务之间会频繁的竞争锁资源,事务可能因为等待锁而被组赛,从而延长用户的的响应时间。
最直观的例子就是:目前有两个事务,事务A在修改数据(但还未提交),与此同时事务B想要查询数据,如果没有MVCC,那事务B就会一直等待事务A的锁释放,这样就很影响读写性能。如果有MVCC,那么事务B就能够直接查到修改前的数据,这样就大大提高了事务的并发度,提升MySQL性能。
2.MySQL中的事务隔离级别有哪些?
1.读未提交,事务a可以读取到事务b未提交的数据,会出现脏读现象
2.读已提交,事务a可以读取到事务b已经提交的数据,会出现不可重复读现象,前后多次读取,数据不一致
3.可重复读,事务a可以读取到相同的数据,可能会出现幻读现象,前后多次读取,数据前后总量不一致
4.串行化,最高级别的隔离等级
关于脏读、不可重复读、幻读的例子如下:
脏读(Dirty Read)
脏读是指一个事务读取了另一个事务未提交的数据。例如,在转账操作中:
- 事务A开始,查询账户余额为2000元。
- 事务B开始,从账户中取款1000元,余额变为1000元,但未提交。
- 事务A再次查询账户余额,读到的余额为1000元(脏读),因为事务B还未提交。
- 事务B因错误回滚,账户余额恢复为2000元。
- 事务A提交,基于错误的脏读数据进行了后续操作,导致错误。
不可重复读(Non-repeatable Read)
不可重复读是指在一个事务中,多次读取同一数据集合时,由于另一个事务的修改,导致读取结果不一致。例如:
- 事务A开始,读取小明的年龄为20岁。
- 事务B开始,将小明的年龄更改为30岁,并提交。
- 事务A再次读取小明的年龄,发现变为30岁,与第一次读取的结果不同。
幻读(Phantom Read)
幻读是指在一个事务中,多次读取同一范围的数据时,由于另一个事务的插入或删除操作,导致读取到的记录数量不一致。例如:
- 事务T1查询id大于2的记录,得到5条数据。
- 事务T2插入一条新的记录,id为6,并提交。
- 事务T1再次查询id大于2的记录,发现现在有6条数据,与第一次查询的结果不同,就像出现了幻觉一样。
我用一套比喻来形容这三种情况
1.脏读是:"被骗了"
2.不可重复读:"谁改我键位了?"
3.幻读:"闹鬼了,出去10个人,回来11个人"。
3.MySQL默认的事务隔离级别是什么?为什么选择这个级别?
默认使用可重复读隔离模式,避免使用读未提交,读已提交隔离导致的幻读和主从数据不一致
4. MySQL 的乐观锁和悲观锁是什么?
悲观锁就是MySQL在操作数据前就对数据加锁,其他事务没有获取锁的话就不能操作数据。
乐观锁就是不会在数据加锁,但每次操作数据会检验前后的版本号或时间戳是否一致,一致的话就说明数据没有被改动,此时可以操作,不一致就说明被改动了,此时不可以操作。
5.MySQL中发生了死锁怎么解决?
MySQL内部有死锁检测机制,检测到死锁就会回滚其中占有资源最少的事务,我们也可以手动kill掉造成死锁的事务。
6.如何使用 MySQL 的 EXPLAIN 语句进行查询分析?
用法就是直接在SQL语句前加上explain关键字,然后主要就是看他的id,type和row
1、id 执行顺序,越大越优先
2、type 执行情况由,好到差是:
(1)system/const 通过主键或唯一索引查询,只有一行命中
(2)eq_ref 主键或唯一索引上的join查询,对于前表的每一行后表只有一行命中
(3)ref 非唯一索引的等值匹配,可能有多行命中
(4)range 索引的范围扫描,比如between 大于 小于
(5)index 索引上的全集扫描,比如count
(6)al 全表扫描,也是性能最差
3.rows 预估扫描的行数,越小越好
具体用法可以看我的另一篇文章:MySQL中explain关键字的用法以及每个字段的含义-CSDN博客
7.MySQL中 count(*)、count(1)和 count(字段名) 有什么区别?
1)count(*)会统计表中所有行的数量,包括u1值(不会忽略任何一行数据)。由于只是计算行数,不需要对具体的列进行处理,因此性能通常较高。
2)count(1)和 count(*)几乎没差别,也会统计表中所有行的数量,包括 null值。
3)count(字段名)会统计指定字段不为 null 的行数。这种写法会对指定的字段进行计数,只会统计字段值不为 null 的行。
8.MySQL 中 int(11) 的 11 表示什么?
在MySQL中,int(11)是一种整数类型的数据定义,其中int表示这是一个整数类型的字段,而括号中的数字11代表的是显示宽度,并不会影响该字段实际存储的数值范围。
具体来说,`int(11)`中的`11`表示在显示结果时,该字段的值将以11个字符的宽度显示。如果实际值的长度小于11,MySQL会根据需要用空格填充;如果实际值的长度大于11,则显示实际值。这个显示宽度对于存储和计算并没有任何影响,仅在显示查询结果时起到对齐的作用。
例如,如果你插入数字`123`到一个`INT(11) ZEROFILL`列中,MySQL可能会将其显示为`000000000123`。如果没有使用`ZEROFILL`,数字将按原样显示,不会有额外的零。所以,`int(11)`实际上可以存储的数值范围是`-2,147,483,648`到`2,147,483,647`(有符号)或`0`到`4,294,967,295`(无符号),与`int`类型的最大值相同。
9.MySQL中 varchar 和 char 有什么区别?
char 表示的是定长字符串,如果实际存储的字符串小于预定的大小,则会使用空格填充是使达到预定长度
varchar 表示可变长度的字符串,实际存储的字符串长度是多少就会占用实际存储的长度+上1--2字节的大小。这1-2个字节是用来记录字符串大小信息的。
一般除非是涉及到身份证号,邮编这种确实格式定了的字符串,都采用varchar比较好
10. MySQL如何对SQL语句进行调优?
SQL优化无非就是三点:命中索引、减少回表
命中索引:
1.联合索引要符合最左匹配原则
2.索引不能进行运算
3.索引不能使用函数
4.对经常出现在where语句后面的字段建立索引
5.对排序的字段建立索引
6.避免使用like %
减少回表:
1.避免使用select * ,select *一般都会走回表
2.使用覆盖索引,即索引中包含select后面所需的所有列,避免回表查询