Mysql面试题
本文最后更新于 46 天前,其中的信息可能已经过时,如有错误请留言

一、SQL 语法题

1、Count 主键和 Count 非主键结果会不同吗

结果可能会不同,原因在于 count 只统计非空值,而主键不能存储 NULL 值,非主键可能存储 NULL 值,因此统计结果可能不一样。

延伸:从性能上:count (*) = count (1) > count (主键)> count (字段)

原因如下:

count (*) 和 count (1) 性能相同的原因在于 mysql 做了特殊处理:

InnoDB handles SELECT COUNT(\*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

count (1) 比 count (主键) 性能更好的原因在于,count 主键的时候,要读取主键的数据,并且判断是否为 NULL(实际上我理解如果 mysql 做一点特殊处理,判断出 count 的是主键的时候,当成 count (1) 处理,应该性能就和 count (1) 相同了,而且因为主键没有 NULL,所以结果也是相同的。)

count (主键) > count (普通字段)这点我有点存疑:因为 count 普通字段性能好不好我理解是要看有没有索引,如果有索引,直接扫描索引就能 count 了,性能就会好不少。对于主键字段,如果没有其他的二级索引,那只能扫描主键索引,扫描主键索引和扫描全表,感觉差不多了吧。

补充:(后来问了关于微软 Copilot 关于这里,微软说全表扫描的性能还是要比扫描主键索引性能要差一点的)

2、Mysql 内连接和外连接有什么区别

1、内连接只返回两个表共有的数据

2、外连接分为两种:左外连接和右外连接,左外连接保留语法中左表中所有的数据,右表中没有的数据用 NULL 填充;右外连接保留语法中右表中的所有数据,左表中没有的数据用 NULL 填充;

3、外连接时,on 和 where 有什么区别

where 会把两张表中不符合条件的结果都过滤掉,相当于是内连接;on 的话,是先连接,然后如果后面接着 where,才会用 where 过滤条件,on 在作为连接条件的时候,如果是外连接,会保留驱动表中的所有记录,即使在被驱动表中没有相匹配的记录。

4、having 和 where 的区别

having 和 where 都是用于过滤:

SELECT department, SUM(salary)
FROM employees
WHERE hire_date >= '2020-01-01'
GROUP BY department
HAVING SUM(salary) > 50000;

区别在于:

1、where 用于 group by 之前对数据进行过滤,having 用于 group by 之后对数据进行过滤

2、where 不能对聚合函数进行筛选,having 可以对聚合函数进行筛选

5、exists 和 in 的区别是什么

select * from A where id in (select id from B);
select * from A where exists (select 1 from where A.id = B.id);

以上一个用 in,一个用 exists,结果相同,性能不同;

A 称为外表,B 称为内表:

内表数据多的时候,用 exists,性能更好,因为不用挨个匹配 B 中的数据

内表数据少的时候,用 in 性能更好,因为不用对于 A 中每一条结果再去查询一次 B 数据库

6、mysql 约束有哪些

1、主键约束:用于唯一标记一条数据,不能重复、不能为 NULL,可以是一个字段,也可以是多个字段复合

2、外键约束:一个表中的外键对于另外一张表的主键。外键是可以重复的,也可以为空。

3、唯一性约束:标记某个字段不能重复

4、非空约束:标记某个字段不能为空

5、默认约束:字段的默认值,在插入数据的时候,如果没有指定字段的值,那么会给字段一个默认的值

6、检查约束:mysql 不支持,如果一定要用检查约束,需要使用触发器或视图

7、delete、drop、truncate 有什么区别

1、delete 记录的时候,只是把该记录标记为已删除,并不会吧磁盘空间回收,所以磁盘文件大小是不会变的,而且用 delete 删除全表,性能会很慢。因为删除一条记录之前,需要先记录 undo log,然后 redo log 要记录 undo log 页的变更,然后 msyql 的 server 层还要记录 binlog,所以很慢。

2、drop 直接把表删除了,在 mysql 里面会把.frm 和.idb 两个文件都删除,表结构也不在了,如果想恢复数据,只能去 server 层找 binlog 了。

3、truncate 最终的效果与先 drop 再创建一张空表类似。truncate 删除的数据,也只能去用 binlog 恢复了。

8、联合查询中 union 和 union all 的区别是什么

union 会去除重复的行;

union all 不会去除重复的行;

所以 union 的性能可能差一点,因为去重很消耗性能。

三、索引结构

1、Mysql 有哪些索引类型

根据数据结构分:B + 树索引、fulltext 索引、hash 索引(memory 引擎)

按物理存储:主键索引、二级索引

按字段特性:唯一索引、前缀索引、普通索引、主键索引

按字段个数:单列索引、联合索引

2、InnoDB 引擎的索引数据结构是什么

B + 树

1、数据组织形式:主键索引 B + 树的非叶子节点只存放索引键值和指向子节点的指针,不存储实际数据,叶子节点存储索引键值和行数据

2、叶子节点链表:所有叶子节点通过指针相连、形成一个双向链表,支持快速的顺序访问和范围查询

3、平衡树结构:所有叶子节点在同一层上,树的高度平衡,保证任何数据记录的查找、插入、删除和更新操作的路径长度相同 ,稳定性好

3、B + 树的特性是什么

重点:

1、叶子节点存储索引 + 数据,非叶子节点只存储索引键值,不存储数据

2、叶子节点之间用双向链表组织

B + 树是一个多叉树,一个父节点对应多个子节点,主要特性有三个:

1、B + 树的非叶子节点不会存储数据,叶子节点才会存储数据,中间节点只用于存储到叶子结点的路由信息(即索引),而且每个节点里的数据都是根据索引的值来顺序存放的

2、B + 树所有的叶子节点之间会通过双向指针串联在一起,构成一个双向链表,方便扫表和范围查询

3、B + 树查询稳定,因为所有叶子节点都在同一层,确保了所有数据项的检索都具有相同的 I/O 延迟。B + 树存储千万级别的数据,B + 树的数据高度也只有 3~4 层,可以大幅减少磁盘 I/O 操作次数。

4、B + 树和 B 树有什么区别

B + 树和 B 树最大的区别在于 B + 树所有的数据都存放在叶子节点中,并且叶子节点通过双向指针串联成双向链表。而 B 树的非叶子节点也存放数据,也没有组织成双向链表。

1、由于 B + 树有双向链表,所以很容易实现范围查找,而 B 树要通过中序遍历实现范围查找,显然中序查找的磁盘 I/O 操作次数会多很多。

2、B + 树查询性能稳定,因为最后都要到叶子节点才能把数据返回,而 B 树查询性能不稳定,可能在非叶子节点就找到数据就返回了。另外还有一点,就是因为 B + 树的非叶子节点只存储索引,这样体积小很多,这样在定位数据的过程中,就避免了读入很多无用的数据记录,同时,减少了磁盘的 I/O 操作开销。

5、mysql 为什么用 B + 树

1、对比于红黑树,B + 树的高度更小,这样对应的磁盘 I/O 操作次数也少,可以大幅减少磁盘 I/O 开销

2、相比于 B 树,B + 支持范围查找

3、相比于跳表:跳表的多级列表高度也是有点高的,对于磁盘 I/O 来说性能差,同样查询性能也不稳定,存在极端情况下,查询性能退化成链表的情况

感谢阅读!如有疑问请留言
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇