java 面试 - 数据库
1.数据库的优化
2.对于索引的理解
个人认为索引是一种在尽可能少的 io 次数和时间下提高查找效率的数据结构,在
innodb 和 myisam 默认为为 b+树索引,b+树除此之外还有 hash 索引。
3.myisam 和 innodb 索引的区别
myisam 索引的数据结构是将索引和数据分开存储。MyISAM 索引文件和数据文件是分离的,索引文件仅保存数据记录的地址,myisam 创建索引会生成三个文件,frm(表定义文件)、myi(存储数据的索引)、md 文件(这个表存储的数据),myisam 叶子结点上存储的是 key 值和数据记录的地址,每次都需要到数据文件上找到相应的数据。innodb 要求表必须要有主键,如果没有会自动生成。
1、在 InnoDB 中,只需要根据主键值对聚簇索引进行一次查找就能找到对应的记录,而在 MyISAM 中需要进行一次回表操作,表示 MyISAM 中建立的索引都是二级索引。
2、InnoDB 的数据文件就是索引文件,而 MyISAM 索引文件和数据文件是分离的。
3、InnoDB 的非聚簇索引 data 域存储相应记录主键的值,而 MyISAM 索引记录的是地址。
4、MyISAM 的回表操作是十分快速的,主要是拿地址偏移量直接到文件中取数据。
5、InnoDB 要求表必须有主键,而 MyISAM 可以没有。
innodb 的回表
当我们使用辅助索引进行查找时,由于叶子结点就保存了主键和索引相应的字段,如果还要更多的数据列,需要去主键索引上去查找,这就是回表。当 sql 语句的所求查询字段(select 列)和查询条件字段(where 子句)全都包含在一个索引中,可以直接使用索引查询而不需要回表。这就是覆盖索引,可以减少一次树的检索,是常用的性能优化手段。
不过在 mysql5.7 后引进了 icp 索引下推的新功能,减少了回表操作。
4.icp 索引下推功能介绍
mysql 架构分为连接层,server 层,存储引擎层,server 层主要是连接器,解析器,优化器。
存储引擎读取索引记录(不是完整的行记录);
判断
WHERE
条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);
存储引擎把记录交给
Server
层,Server
层检测该记录是否满足WHERE
条件的其余部分。
select * from tuser where name like '张%' and age=10;
上述代码,使用 icp 和不使用 icp 的区别如,不使用 icp 存储引擎相当于只执行了 like 后的语句,然后进行回表,对于 age 的条件则交给 server 层去处理。而使用了 icp 后,则存储引擎,使用联合索引对 age=10 过滤之后再去进行回表查找,这样剩下的交给 server 层去处理。所以相当于有两个好处:减少回表次数,减少 server 层的压力。
5.索引失效的情况
or 连接,其中一项不符合索引条件。
使用函数,表达式类型转换。
使用反向查询,例如!=,not like 等。
lik 以通配符开头。
6.btree 和 b+tree、hash 索引
个人理解索引
3 层 b 树大概能存 100 万数据,而 3 层 b+树大概能存二千万数据,差距主要在于 b 树
B+树改进了 B 树, 让内结点只作索引使用, 去掉了其中指向 data record 的指针, 使得每个结点中能够存放更多的 key, 因此能有更大的出度. 这有什么用?
这样就意味着存放同样多的 key, 树的层高能进一步被压缩, 使得检索的时间更短.
(2)当然了,由于底部的叶子结点是链表形式, 因此也可以实现更方便的顺序遍历, 但是这是比较次要的, 最主要的的还是第(1)点.
7.数据库出现的问题
数据库连接爆满问题,个人虽然没有解决过类似的问题,但是个人认为,主要是两个方面,一个是空闲连接是否没有释放,第二个是活动连接是否阻塞。第一个设置连接释放时间的参数即可,或者最大连接数。第二个可能出现的问题有慢查询、cpu 使用率过高、iops、innodb 锁等待。cpu 使用率高主要几个问题导致,负载高,慢查询。这两个问题都可以通过监控后台查到,具体的优化手段,负载高的话,可以通过增加配置, 分库分表,垂直分表水平分表、读写分离、开启查询缓存,优化表数据结构、采用 redis 缓存的方式。
慢查询的优化方式。
评论