MySQL 高频面试题

1、什么是索引?
索引是一种数据结构,帮助我们快速的进行数据查找。
2、索引是什么样的数据结构?
索引的数据结构与使用的存储引擎实现有关,在MySQL中使用较多有Hash索引和B+树索引等,而我们经常使用的InnoDB存储引擎默认的索引实现为B+树索引。
3、Hash索引和B+树索引有什么区别或者说优劣呢?
先说hash索引
hash索引底层就是hash表,进行数据查找时,执行一次hash函数就可以获取相应的键值,之后进行回表查询获取实际的数据。
hash索引进行等值查询更快,但无法进行范围查询、不能排序、不能使用组合索引的最左前缀匹配。
原因是因为hash索引经过hash函数建立索引后,索引顺序无法与原顺序保持一致。
hash索引任何时候都避免不了回表查询。
然后说B+树索引
B+树底层实现是多路平衡查找树.对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。
B+树支持范围查询、支持排序、支持组合索引的最左前缀匹配。
原因是因为B+树的的所有节点皆遵循左节点小于父节点,右节点大于父节点。
B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询.不需要回表查询。
4、什么是聚簇索引(什么是主键索引,和普通索引有什么区别)?
在B+树索引中,聚簇索引的叶子节点包含所有字段,非聚簇索引(也叫二级索引)只包含索引字段+主键字段(或主键指针)。在InnoDB中,只有主键索引是聚簇索引,如果没有主键则挑选一个唯一键建立聚簇索引,然后没有唯一键则隐式生成一个键来建立聚簇索引。
5、什么是覆盖索引?
当查询使用聚簇索引或查询所要求的全部字段都命中了索引,不需要回表查询,那么就是覆盖索引。
6、在建立索引都有哪些考虑因素?
首先考虑的是字段的使用频率,经常作为条件去进行查询的字段比较合适。并且表数据较多的时候,值分布大(选择性较好的),创建索引会明显地提高查询速度。
(经常与其他表进行连接的表,在连接字段上应该建立索引)
然后需要建立组合索引的话,还需要考虑遵循他的最左前缀匹配。
此外还需要考虑其他方面,如过多的建立索引会导致对插入、更新、删除的开销,减低处理数据的性能。
7、组合索引是什么?为什么需要遵循他的最左前缀匹配
Mysql可以使用多个字段同时建立一个索引,叫组合索引。
具体原因是:MySQL在建立组合索引时是先按第一列进行排序,然后在第一列排好序的基础上再对第二列排序,然后没有第一列直接访问第二列的话,那肯定是无序的,直接访问后面的列也就用不到索引了。
8、创建的索引有没有被使用到,或者说怎么才知道这条语句运行很慢的原因?
MySQL提供了explain命令来查看语句的执行计划,MySQL在执行语句之前,会将该语句从查询优化器过一遍,之后会拿到对语句的分析,也就是执行计划,其中包含了许多信息,可以通过其中对索引有关的信息来分析是否命中了索引,例如possibe_key、key、key_len、type等字段,分别说明了此语句可能会使用到的索引,实际使用到的索引以及使用的索引长度,还有就是访问类型,表示在表找到所需行的方式,他有几个值,性能从好到差分别是 const、eq_ref、ref、range、index、All。
9、那么在哪些情况下会发生创建了索引但在查询时候没有用到呢?

  • 索引字段是 字符串类型,查询条件是数字型的,类型不匹配索引失效
  • 在索引列进行运算操作
  • where条件 以%开头like模糊查询
  • where条件not 、 !=、<> 、not in不使用索引
  • where条件or 两边的字段都需要带有索引,否则索引失效
  • 使用了范围查找(>、<、between、like)、查出的量大不使用索引【后面的字段不使用索引】
  • 组合索引没有遵循最左原则
  • mysql评估认为全表扫描会更快时不使用索引
  • 使用 is null、is not null 有时索引失效(值少的时候)
    10、对语句是怎么优化过的
    在业务系统中,除了使用主键进行的查询,其他的我都会在测试库上测试其耗时,并开启一段时间的慢查询记录开关,来得到查询语句。
    慢查询的优化首先要搞明白慢的原因是什么?是查询条件没有命中索引,还是查询出不需要的数据列,还是数据量太大了。
    所以优化针对这三个方向来。
  • 首先分析语句,是否加载了额外的数据,可能查询多余的行并且抛弃掉了,可能查询并不需要的列,对语句进行分析以及重写。
  • 分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或修改索引,使其语句可以尽可能的命中索引。
  • 如果对语句的优化已经无法进行,可以考虑表中的数据是否过大,如果是的话可以进行横向或纵向的分表。
    11、上面提到横向分表和纵向分表,可以分别举一个适合他们的例子吗?
  • 横向分表是按行分表.假设我们有一张用户表,主键是自增ID且同时是用户的ID.数据量较大,有1亿多条,那么此时放在一张表里的查询效果就不太理想.我们可以根据主键ID进行分表,无论是按尾号分,或者按ID的区间分都是可以的.
    假设按照尾号0-99分为100个表,那么每张表中的数据就仅有100w.这时的查询效率无疑是可以满足要求的.
  • 纵向分表是按列分表.假设我们现在有一张文章表.包含字段id-摘要-内容.而系统中的展示形式是刷新出一个列表,列表中仅包含标题和摘要,当用户点击某篇文章进入详情时才需要正文内容.此时,如果数据量大,将内容这个很大且不经常使用的列放在一起会拖慢原表的查询速度.我们可以将上面的表分为两张.id-摘要,id-内容.当用户点击详情,那主键再来取一次内容即可.而增加的存储量只是很小的主键字段.代价很小.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值