文章目录
- 基础篇
- 非关系型数据库和关系型数据库的区别?
- MySQL 数据库两种存储引擎的区别?
- 索引篇
- 为什么索引能提高查询速度?
- 聚集索引和非聚集索引的区别?非聚集索引一定回表查询吗?
- 索引这么多优点,为什么不对表中的每一个列创建一个索引呢?(使用索引一定能提高查询性能吗?)
- Hash 索引和 B+树索引优劣分析
- B+树做索引比红黑树好在哪里?
- 最左前缀匹配原则了解么?
今天给大家推荐几道常见的MySQL面试题,来试试你能答对几道?
基础篇
非关系型数据库和关系型数据库的区别?
🙋♂答:
- 存储数据的类型不同。
关系型数据库使用二维的表来进行存储;非关系型数据库有多种数据存储方式,比如Redis使用K-V存储。 - 查询效率不同。
关系型数据库的数据是持久化了的。只能和硬盘进行I/O;而非关系型数据库可以存储在硬盘上,也可以存储在内存中,从内存读取数据要比硬盘快得多。在处理大量数据时,可以考虑使用非关系型数据库来提升效率。
MySQL 数据库两种存储引擎的区别?
🙋♂答:
- 对事务的支持:InnoDB存储引擎支持事务,MyISAM不支持事务。也正是这样,所以大多数 MySQL 的引擎都是用 InnoDB。
- 执行SELECT COUNT() FROM TABLE 效率:MyISAM引擎中直接保存了表的行数,当执行SELECT COUNT() FROM TABLE 时,就不需要进行全表扫描。
- 加锁级别:InnoDB锁的细粒度比MyISAM高,InnoDB有行级锁,MyISAM最高是表级锁。
综上所述:如果数据库读的操作远远多于写的操作,并且对事务无要求,可以考虑使用MyISAM;如果对于并发量比较大的场景,使用InnoDB。
索引篇
为什么索引能提高查询速度?
🙋♂答:
如果不使用索引,MySQL直接走全表扫描,这样查询到想要的数据可能会进行很多次磁盘I/O,是很浪费时间的;如果使用索引,比如MySQL使用B + 树作为索引,B + 树就是很高效的数据结构,可以有效减少磁盘I/O的次数。
B+Tree 存储千万级数据只需要 3-4 层高度就可以满足,从千万级的表(1000 * 1000 * 16)查询目标数据最多需要 3-4 次磁盘 I/O。
聚集索引和非聚集索引的区别?非聚集索引一定回表查询吗?
🙋♂答:
聚簇索引的叶子节点存放的是实际数据,所有完整的用户记录都存放在叶子节点。
一般情况下会使用主键作为聚簇索引,由于一张表只能有一个聚簇索引,为了实现非主键字段的快速搜索,就引出了二级索引(非聚簇索引/辅助索引),它也是利用了 B+ 树的数据结构,但是二级索引的叶子节点存放的是主键值,不是实际数据。
第二个问题:
首先要知道回表是什么?
回表,就是先检索二级索引,找到叶子节点并获取主键值,通过聚簇索引查询到对应的叶子节点,也就是要查两个 B+Tree 才能查到数据。
显而易见的,非聚簇索引不一定需要回表操作。索引覆盖,覆盖索引是指 SQL 中 查询 的所有字段,都能直接从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表的操作,也就是只需要查一个 B+Tree就能找到数据。
举例:
select id from product where product_no = '0002';
这种在二级索引的 B+Tree 就能查询到结果的过程就叫作「覆盖索引」,也就是只需要查一个 B+Tree 就能找到数据。
索引这么多优点,为什么不对表中的每一个列创建一个索引呢?(使用索引一定能提高查询性能吗?)
🙋♂答:
索引也有缺点:
- 首先,索引是一种数据结构,也需要占用磁盘空间。并且创建、维护索引要耗费时间,这种时间随着数据量的增加而增大;
- 索引有可能失效。
索引也有适用范围:
- 字段有唯一性限制,比如商品编码。
- 经常用于 WHERE 查询条件、GROUP BY 和 ORDER BY 的字段。
- 在查询的时候就不需要再去做一次排序了,因为 B+Tree 的记录都是有序的。
相对应的也有不适合适用索引的时候:
- 字段中存在大量重复数据,不需要创建索引。
- MySQL 有一个查询优化器,查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。
- WHERE 条件,GROUP BY,ORDER BY 里用不到的字段。
- 因为索引的价值是快速定位,如果起不到定位作用的字段不需要创建索引。
- 表数据太少的时候,不需要创建索引。
- 如果字段经常更新,不需要创建索引。
- 维护B + 树的结构,就需要频繁重建索引,影响数据库性能。
Hash 索引和 B+树索引优劣分析
🙋♂答:
优势等值查询:在查询速度上,如果是等值查询,那么Hash索引明显有绝对优势,因为只需要经过一次 Hash 算法即可找到相应的键值,复杂度为O(1)。
劣势:
- 无法范围查询: Hash 索引是无序的,如果是范围查询检索,这时候 Hash 索引就无法起到作用,即使原先是有序的键值,经过 Hash 算法后,也会变成不连续的了。
- 无法使用联合索引: 并且Hash索引不支持联合索引查询。
- 存在哈希碰撞问题: 在有大量重复键值情况下,哈希索引的效率极低。
综上:大多数场景下,都会有组合查询,范围查询、排序、分组、模糊查询等查询特征,Hash 索引无法满足要求,建议数据库使用B+树索引。
在离散型高,数据基数大,且等值查询时候,Hash索引有优势。
B+树做索引比红黑树好在哪里?
🙋♂答:
红黑树(Red Black Tree)是一种自平衡的二叉查找树,它与平衡二叉树相同的地方在于都是为了维护查找树的平衡而构建的数据结构,它的主要特征是在二叉查找树的每个节点上添加了一个属性表示颜色,颜色有两种,红与黑。
当数据量特别大的时候,会导致红黑树的高度变高,磁盘IO操作次数就会变多,影响整体数据查询效率。
最左前缀匹配原则了解么?
🙋♂答:
联合索引按照最左匹配原则,如果创建了一个 (a, b, c) 联合索引,查询条件存在a就可以匹配上联合索引,比如where a=1;
联合索引的最左匹配原则会一直向右匹配直到遇到范围查询(>、<)就会停止往下使用联合索引。也就是范围查询的字段可以用到联合索引,但是在范围查询字段之后的字段无法用到联合索引。注意,对于 >=、<=、BETWEEN(类似于>=、<=)、like 前缀匹配,这类范围查询,并不会停止使用索引,两个字段都会用到联合索引查询,但是只是 = 的部分用到了。
比如联合索引
(a,b)
,a全局有序(1,2,2,3,4,5),b是全局无序的(12,7,8,2,3,1)。因此,直接执行where b = 2这种查询没办法利用联合索引。利用索引的前提是,索引里的key是有序的。只有在 a 相同的情况才,b 才是有序的,比如 a 等于 2 的时候,b 的值为(7,8),这时就是有序的,这个有序状态是局部的,因此,执行
where a = 2 and b = 7
是 a 和 b 字段能用到联合索引的,也就是联合索引生效了。