MySQL常问面试题
什么是事务?
事务就是逻辑上的一组操作,要么都执行,要么都不执行
ACID是什么?
原子性
就是之前说过的事务,要么都成功,要么全部都失败,不可能只执行其中的一部分操作
一致性
就是,系统(数据库)从一个一致性的状态转移到拎一个一致性状态,不会存在中间的态
隔离性
通常来讲,一个事务在完全提交之前,对其他的事务是不可见的,有可能出现例外的情况
持久性
一旦事务提交了,那么就永远是这个样子了,不糊进行更改了,哪怕系统崩溃都不会去影响这个结果
并发事务会带来什么问题
脏读
当一个事务正在访问数据并且对数据进行了修改,而这种修改环没有提交到数据库中,这时,另一个事务也访问了这个数据,然后使用了这个数据,因为这个数据是还没有提交的数据,那么另一个事务读到的这个数据就是“脏数据”依据“脏数据”所做的操作可能是不正确的。
幻读
他发生在一个事务(T1)读取了几行数据,接着另一个并发的事务(T2)插入了一些数据时,在随后的查询中,第一个事务(T1)就会发现多了一些不存在的记录,就好像发生了幻觉一样,所以叫做幻读
不可重复度
指的就是,一个事务内多次读同一个数据,在这个事务读取的过程中,第二个事务也访问了这个数据,并对这个数据进行了修改,那么第一个事务在读取的时候,发现第一次读取的数据和第二次读取的数据不一样,因此称为不可重复读幻读和不可重复读有啥区别
并发事务发生了这些问题,有什么解决方案?(mysql的事务隔离级别)
读未提交
这个隔离级别下,其他的事务可以看到本事务没有提交的部分,因此会造成脏读的现象,这个级别的性能没有主足够大的优势,所以使用很少
读已提交
其他的事务只能读到本事务已经提交的的部分,这个隔离级别有不可重复读的问题,在同一个事务中俩次的读取,拿到的结果竟然不一致,因为另一个事务已经对数据进行了修改
可重复读
可重复读的隔离级别就是解决不可重复读的问题,但是任有一个问题就是幻读,举个栗子,就是你要读取id>10的数据,对涉及到的行加上了行锁,此时,另一个事务新插入了一个id为19的数据,因为是新插入的不会触发上面的行锁的排斥,那么本事务在进行下一次查询的时候就会发现多了一条id为19的数据,而上一次查询的时候是没有的,如果你在进行性插入的时候就会发生主键冲突的问题
可串行化
这是最高的隔离级别,可以解决上面的所有问题,因为他强制将所有的操作串行执行,这会导致并发性能急速下降,因此不会经常使用
mysql中有哪几种锁?
1、表级锁
开销小 加锁快 不会出现死锁 锁粒度大 发生锁冲突的概率高 并发度低
2、行级锁
开销大 加锁慢 会出现死锁 锁粒度小 发生锁冲突的概率最低 并发度也是最高
3、页面锁
开销和加锁时间介于表锁和行锁之间 会出现死锁 锁粒度在表锁和行锁之间 并发度一般
从类别上讲分为共享锁和排它锁
1、共享锁
又叫读锁,当用户惊醒数据的读取时,对数据加上共享锁,共享锁可以加上多个
2、排它锁
又叫写锁,当用户进行数据的写入的时候对数据加上排它锁,排它锁只可以加一个,他和其他的共享锁,排他锁都排斥
如何优化SQL
1、SQL语句中的IN包含的值不应过多
简单一点讲的话,就是能用between就不要用in,做或者使用连接来替换
2、select语句务必指名字段
select * 增加了许多不必要的小号,增加了覆盖索引的可能性
3、如果限制条件中的其他字段没有索引,尽量少用or
如果有一个不是索引字段,而其他条件也不是索引字段,就会造成该查询不走索引的情况
4、避免在where子句中对字段进行null值判断
对null值判断会导致引擎放弃使用索引
5、避免在where子句中进行表达式的操作
select user_id,user_project from table_name where age*2=36;
改成
select user_id,user_project from table_name where age=36/2;