解析:
MySQL 可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命
中索引,需要按照建立索引时的字段顺序挨个使用
,否则无法命中索引。
具体原因为:
MySQL 使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,
那么索引的排序为: 先按照 name 排序,如果 name
相同,则按照 age 排序,如果 age 的值也相等,则按照 school 进行排序。
当进行查询时,此时索引仅仅按照 name 严格有序,因此必须首先使用 name 字段进行
等值查询,之后对于匹配到的列而言,其按照 age 字段
严格有序,此时可以使用 age 字段用做索引查找,以此类推。因此在建立联合索引的时候应
该注意索引列的顺序,一般情况下,将查询需求频繁
或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。
解析:
脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由
于某些原因,前一个 RollBack 了操作,
则后一个事务所读取的数据就会是不正确的。
不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,可能是两次查
询过程中间插入了一个事务更新的原有的数据
幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了
几列(Row)数据,而另一个事务却在此时插入了
新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
解析:
SQL 标准定义了四个隔离级别:
READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可
能会导致脏读、幻读或不可重复读。
READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但
是幻读或不可重复读仍有可能发生。
REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本
身事务自己所修改,可以阻止脏读和不可重复读
,但幻读仍有可能发生。
SERIALIZABLE(可串行化):最高的隔离级别,完全服从 ACID 的隔离级别。所有事务依次逐
个执行,这样事务之间就完全不可能产生干扰
,也就是说,该级别可以防止脏读、不可重复读以及幻读。
解析:
在 Read Uncommitted 级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的
排他锁冲突;
在 Read Committed 级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;
在 Repeatable Read 级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,
也就是必须等待事务执行完毕以后才释放共享锁。
SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直
到事务完成。
解析:
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循
环的现象。
常见的解决死锁的方法:
如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死
锁产生的概率;
如果业务处理不好可以用分布式事务锁或者使用乐观锁。