目录
1、mysql的存储引擎?有什么区别?优点,缺点,什么场景是用什么?
2、innodb是什么索引?为什么查主键索引会比较快?
3、说一下 mysql 的行锁和表锁?
4、事务是什么?mysql事务的特性?ACID?MySQL并发事务带来的问题?事务隔离级别?mysql默认隔离级别?
5、数据库事务的实现原理?
6、怎么验证 mysql 的索引是否满足需求?
7、 说一下乐观锁和悲观锁?
8、mysql 问题排查都有哪些手段?
9、如何做 mysql 的性能优化?
10、索引是什么? 分类? 作用? 索引失效? 失效原理?(最左前缀)
11.MVCC是什么?MVCC的实现原理?
12.mysql 和 redis的适应场景
13.MySQL性能分析Explain(执行计划)?
14.覆盖索引(索引覆盖)?
15.索引优化(即如何防止索引失效)?
16.解决like'%字符串%' 索引失效的方法?
18.为什么要分库分表?(待补充)
19.b+树?
20.聚簇索引与非聚簇索引?
答:MyISAM和InnoDB,InnoDB是mysql5.5及之后默认使用的存储引擎。InnoDB支持事务、外键,MyISAM不支持。MyISAM只缓存索引,不缓存真实数据。而InnoDB不仅缓存索引还要缓存真实数据。MyISAM不适合高并发的操作,因为它是表锁,操作一行记录会锁住整张表,而InnoDB是行锁,写操作是不会锁定全表的,适合并发度较高的场景。MyISAM当进行 select count(*) from table 语句时,不需要进行全表扫描,因为它底层维护了一个计数器,提前将表的总行数存储起来,定期维护。而InnoDB需要进行全表扫描。如果表的读操作远远多于写操作时,并且不需要事务支持的,可以考虑用MyIASM。
InnoDB是聚簇索引,数据文件和索引文件是绑在一起的。MyISAM是非聚簇索引,索引文件与数据文件是分离的。InnoDB的B+树主键索引的叶子节点存放的就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。
答:innodb是聚簇索引。因为innodb的主键索引与数据文件是绑在一起的,而辅助索引的话就得需要两次查询才能找到数据,先查询到主键,然后再通过主键查询到数据。因此主键不应该过大,因为主键过大的话,索引也会变大。
答:MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。表级锁:开销小,加锁快,不会出现死锁。锁粒度大,发生锁冲突的概率最高,并发量最低。行级锁:开销大,加锁慢,会出现死锁。锁粒度小,发生锁冲突的概率小,并发度最高。
答:事务是SQL语句被当做一个整体,要么都执行成功,要么都执行失败。四大特性。原子性、一致性、隔离性、持久性。原子性指的是一个事务里的命令要么全部执行,要么全部不执行,如果中间发生了错误,会导致前面的命令回滚,后面的命令不再执行。一致性指执行事务前后,数据保持一致。例如银行转账,不管转账成功与否,转账前后总额是不变的。隔离性指的是一个事务执行不会影响另一个事务的执行。持久性指的是事务完成之后,对数据库所做的更改将持久地保存在数据库中,并不会被回滚。并发事务带来的问题有脏读、丢失更新、不可重复读、幻读。脏读指的是一个事务对数据进行了修改还没有提交到数据库中,若此时另一个事务前来查询这条数据,查到的就是未提交的数据,即”脏数据“,如果刚才那条数据回滚了,则查询到的数据是无效的。不可重复读是指一个事务内两次读到的数据是不一样的情况,由于另一个事务对数据进行了修改并提交,导致第二次读到的数据不一致的情况。幻读的重点在于新增或者删除,第一个事务刚开始读取到几行数据,第二个事务进行了删除或修改后,第一个事务再去读取就会发现多了或少了几行数据,就像发生了幻觉一样。丢失更新指的是当两个或多个事务修改同一行,由于不知道其它事务的存在,最后的更新覆盖了其他事务所做的更新,导致更新丢失。mysql默认隔离级别有读未提交、读已提交、可重复读、串行化。默认隔离级别是可重复读。
答:以 MySQL 的 InnoDB 引擎为例来简单说一下。MySQL InnoDB 引擎使用redo log(重做日志)保证事务的持久性,使用undo log(回滚日志)来保证事务的原子性。MySQL InnoDB 引擎通过锁机制、MVCC等手段来保证事务的隔离性(默认支持的隔离级别是 REPEATABLE-READ
)。保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。
原子性实现:是用undolog实现的,undolog的意思是回滚日志,指的是每次在有写命令的时候,会先向undolog中写入一份,如果中间发生了故障,就可以通过undolog进行回滚,比如说如果是insert命令只要delete就可以了,delete命令只要insert就可以了,update命令只要更新回原来的值就可以了。
持久性实现:是用redolog实现的,重做日志,mysql在读取或者修改数据的时候并不是直接进行读取修改的,而是用到了缓存的概念,因为如果每次读取修改都要对数据库进行操作,那么会对mysql造成压力,所以先对缓存进行操作,再对mysql进行操作。如果读取数据的话,先从缓存中读取,如果缓存中没有,才从mysql中读取,然后再丢到缓存中。修改数据的话也是先修改缓存,再修改数据库,但是这样的话会出现问题,如果修改了缓存,但是还没有同步到数据库中,这时候假如mysql宕机了,就会发生数据不一致的问题;所以每次再有写命令的时候,先向redolog中写入,再写入缓存,要是mysql宕机了,我们也可以靠redolog进行恢复;
隔离性实现:隔离性实现有两种方式,一种是MVCC多版本并发控制,一种是加锁。通过MVCC可以解决读-写问题,通过锁机制可以解决写-写问题,
答:使用 explain 查看SQL是如何执行查询语句的,从而分析你的索引是否满足需求。
答:乐观锁就是每次去拿数据的时候都认为别人不会修改,所以不会上锁。但是在提交更新的时候会判断一下别人有没有修改这条数据。悲观锁就是每次去拿数据的时候都会认为别人会修改,所以每次去拿数据的时候都会上锁,这样别人拿这个锁就必须等当前锁释放。
答:使用explain查询sql语句执行计划。
使用show processlist命令查看当前所有连接信息。
开启慢查询日志,查看慢查询的sql。
为搜索字段创建索引。
避免使用 select *,列出需要查询的字段。
垂直分库分表。
选择正确的存储引擎。
答:索引是排好序的快速查找数据结构。按物理角度索引分为聚集索引和非聚集索引。按逻辑角度索引分为普通索引、唯一索引、组合索引、主键索引、全文索引。
答:MVCC是多版本并发控制,是一种用来解决读-写冲突的无锁并发控制。主要适用于mysql的RR、RC。我认为mvcc其实就是乐观锁的一种实现,如果乐观锁是接口的话,那么mvcc就是它的实现类。而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现。快照读就是非阻塞的读,也就是不加锁的读。MVCC的实现原理主要是依赖于记录中的三个隐式字段、undolog日志、Read View来实现的。三个隐式字段分别是事务id、隐式主键、回滚指针。事务id是指创建或最后一次修改这条记录的事务id,隐式主键是表如果没主键的话,会自动生成一个主键。回滚指针主要配合undolog日志使用,用于指向上一个版本。Read View是事务进行快照读操作的时候生产的读视图。Read View有三个全局属性,分别是活跃事务id列表、活跃列表里最小的事务id以及生成时刻系统尚未分配的下一个事务id。它还有一个比较规则就是快照读取到的事务id先去与活跃事务id列表中的最小id去比较,如果小于,则当前的这条记录是可见的。如果不符合条件,则再比较事务id是否大于等于系统尚未分配的事务id,如果满足则说明当前事务id是在读视图生成之后产生的,则不可见。如果这个也不符合,那么继续判断当前事务id是否在活跃事务id列表中,如果在的话则说明还未提交,则不可见。不在的话则说明已经提交,可见。还有就是mvcc在RR和RC级别下生成Read View的策略不同,RR级别下,用的一直是第一次快照读生成的读视图,而RC级别下,每次都会生成一个新的读视图,所以RR解决了不可重复读问题。
答:mysql用来存储数据,redis用作缓存,因为redis是在内存中操作数据,所以很快,读的速度是110000次/s,写的速度是81000次/s,可以帮助我们应对高并发的情况
答:id是id相同的话顺序由上至下,id不同的话,id越大的越先被执行。select_type里面有六种类型分别是SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、UNION RESULT。SIMPLE就是简单查询,没有子查询或UNION;PRIMARY就是复合查询的最外层查询;SUBQUERY就是子查询;DERIVED是子查询位于FROM子句;UNION查询处于内层的SELECT、UNION RESULT union操作的结果,id值通常为NULL。table就是这一行数据是关于哪张表的;type显示了查询的类型、最好到最坏依次是system、const、eq_ref、ref、range、index、ALL。system是单表只有一行记录、const是查询单表单行数据、eq_ref是多表联合查询,一对一的关系,唯一索引对唯一索引、ref是多表联合查询一对多的关系、用到索引查出多条记录、range是范围内扫描 例如between and in之类的、index是全索引扫描、ALL是全表扫描。possible_keys是这张表可能用到的索引、key是实际用到的索引,若查询中若使用了覆盖索引,则该索引仅出现在key列表中。key_length是查询中索引的最大可能长度,长度越短越好。ref指的是索引的哪一列或常量被使用了、rows大致估算出找到所需记录所需要的行数,越少越好。Extra有Using filesort文件内排序不好,Using temporary使用临时表存储数据更不好,Using index使用了覆盖索引好 Using where表明使用了where过滤。impossible where表明where子句前后矛盾,比如where name='张三' and name='李四'。
答:查询列要被所建的索引覆盖。explain执行计划为Using index时,触发覆盖索引,mysql官网表达了在一颗索引树上就能获取sql所需的所有列的数据,无需回表,速度更快。
答:全值匹配、最佳左前缀法则、索引列上少计算比如mysql自带的left函数、范围之后全失效、尽量使用覆盖索引(索引列和查询列尽量保持一致),减少select *、不等非空还有or不使用、like百分写右边、VARCHAR要加单引号
答:用覆盖索引去解决。
答:为了防止上亿数据、高流量、高并发压垮数据库,造成数据库性能下降。垂直分库和垂直分表都是按业务来进行拆分,每个数据库存300-500万数据,所以要分库,表的话字段太多数据加载会很慢,而且返回给用户过程中,网络IO、磁盘IO也有一定的消耗。优点就是按业务拆分很清晰,不同业务跑在不同机器上。缺点是如果单表数据量大,读写压力大。水平分库分表指的是每个库表的结构都一样,数据不一样。
答:非叶子节点不存储数据,只进行数据索引。所有数据都存储在叶子节点中。每个叶子节点都存有相邻叶子节点的指针。叶子节点按照本身关键字从小到大排序。
答:InnoDB是聚簇索引,数据文件和索引文件是绑在一起的。MyISAM是非聚簇索引,索引文件与数据文件是分离的。InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。一个表当中只能有一个聚簇索引,而非聚簇索引可以有多个。聚簇索引减少回表查询。