面试准备-数据库篇

    mysql会问到的一些知识点,学习过程中如有错误,欢迎私聊我纠正。

面试准备–Mysql常用的知识点

面对大型的数据库为了避免读取速度的降低应该采用哪些方法(or应该避免哪些操作)

答:(1)没有索引或者没有用到索引(程序设计的缺陷);
(2)I/O吞吐量小,形成了瓶颈效应;
(3)没有创建计算列导致查询不优化;
(4)内存不足;
(5)网络速度慢;
(6)返回了不必要的行;
(7)锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷);
(8)sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。

面对亿级的数据库的时候 有哪些可以考虑的优化方式?

1.SQL以及索引的优化是最重要的。首先要根据需求写出结构良好的SQL,然后根据SQL在表中建立有效的索引。但是如果索引太多,不但会影响写入的效率,对查询也有一定的影响。
2.要根据一些范式来进行表结构的设计。设计表结构时,就需要考虑如何设计才能够更有效的查询。
3.系统配置的优化。MySQL数据库是基于文件的,如果打开的文件数达到一定的数量,无法打开之后就会进行频繁的IO操作。
4.硬件优化。更快的IO、更多的内存。一般来说内存越大,对于数据库的操作越好。但是CPU多就不一定了,因为他并不会用到太多的CPU数量,有很多的查询都是单CPU。另外使用高的IO(SSD、RAID),但是IO并不能减少数据库锁的机制。所以说如果查询缓慢是因为数据库内部的一些锁引起的,那么硬件优化就没有什么意义。

间隙锁、意向锁(意向共享锁和意向排他锁)

间隙锁:当我们用范围条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做”间隙(GAP)”。InnoDB也会对这个”间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。

1
2
3
4
5
6
7
8
Transaction-A  
mysql> update innodb_lock set k=66 where id >=6;
Query OK, 1 row affected (0.63 sec)
mysql> commit;

Transaction-B
mysql> insert into innodb_lock (id,k,v) values(7,'7','7000');
Query OK, 1 row affected (18.99 sec)

危害(坑):若执行的条件是范围过大,则InnoDB会将整个范围内所有的索引键值全部锁定,很容易对性能造成影响。
意向锁的存在是为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。
1)意向共享锁(IS锁):事务在请求S锁前,要先获得IS锁
2)意向排他锁(IX锁):事务在请求X锁前,要先获得IX锁
例子:事务A修改user表的记录r,会给记录r上一把行级的排他锁(X),同时会给user表上一把意向排他锁(IX),这时事务B要给user表上一个表级的排他锁就会被阻塞。意向锁通过这种方式实现了行锁和表锁共存且满足事务隔离性的要求。
意向锁是表级锁。

快速理解脏读、不可重复读、幻读和MVCC

1.MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read.
2.Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.
原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。
3.串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。
4.通过以上总结,可知,MVCC主要作用于事务性的,有行锁控制的数据库模型。
https://cloud.tencent.com/developer/article/1450773
多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。 这样在读操作不用阻塞写操作,写操作不用阻塞读操作的同时,避免了脏读和不可重复读乐观并发控制。 (OCC)是一种用来解决写-写冲突的无锁并发控制,认为事务间争用没有那么多,所以先进行修改,在提交事务前,检查一下事务开始后,有没有新提交改变,如果没有就提交,如果有就放弃并重试。乐观并发控制类似自旋锁。乐观并发控制适用于低数据争用,写冲突比较少的环境。

索引,给表创建索引的原则?

1.对于查询频率较高的字段;
2.对分组,排序,联合查询频率高的字段;
3.索引的数目不宜过多;
4.若在实际中,需要将多个列设置索引时,可以采用多列索引;选择唯一性索引;
5.尽量使用数据量少的索引;
6.尽量使用前缀来索引;(索引字段的值很长时,如TEXT类型);
7.删除不再使用或者很少使用的索引;

索引失效的条件?

1.不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描;
2.存储引擎不能使用索引范围条件右边的列;
3.尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *;
4.mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描;
5.is null,is not null也无法使用索引 —- 此处存在疑问,经测试确实可以使用,ref和const等级,并不是all;
6.like以通配符开头(’%abc…’)mysql索引失效会变成全表扫描的操作。模糊查询查询条件前缀模糊不会走索引;

总结

坚持原创技术分享,您的支持将鼓励我继续创作!