Skip to content

MySQL 待完善

SQL 语法

count 主键和 count 非主键结果会不同吗?

不一定相同。

  1. 主键是非 NULL 的,count 主键会返回所有条数
  2. 非主键可能存在 NULL值,会返回指定列的非 NULL 条数

MySQL 内连接、外连接有什么区别?

内外连接都用于连表查询。

  • 内连接的结果是两个查询的交集。
  • 外连接的结果是其中一个结果和两个结果的交集的并集部分,未匹配到的用 NULL 填充。

外连接时 on 和 where 过滤条件区别?

在内连接中,on 和 where 相同。

在外连接中,on 是连接条件,where 是过滤条件。

having 与 where 的区别?

where 在 group by 分组之前过滤

having 在 group by 分组之后过滤

delete、drop、truncate 有什么区别?

  • delete:删除表的数据,逻辑删除,可以回滚。
  • drop:直接删除表和表结构,不能回滚
  • truncate:删除表中所有记录,不能回滚

❓联合查询中 union 和 union all 的区别是什么?

数据库三大范式是什么?

  1. 第一范式:属性不可再分
  2. 第二范式:有主键,非主键字段依赖主键
  3. 第三范式:非主键字段不能相互依赖

开发不必满足三大范式,可以设计冗余字段

count(*) 性能比 count(1) 好吗?

两者性能相同。MySQL 中,count(*) 会被优化器优化成 count(0)。

count(*) = count(1) > count(主键) > count(非索引字段)

sql 语句执行优先级

  1. FROM:首先从指定的表中获取数据。
  2. JOIN:如果有连接操作,会在 FROM 之后进行。
  3. WHERE:对获取的数据进行过滤。
  4. GROUP BY:在过滤后的数据上进行分组。
  5. HAVING:对分组后的数据进行过滤。
  6. SELECT:选择需要的列。
  7. DISTINCT:去除重复的结果。
  8. ORDER BY:对结果进行排序。
  9. LIMIT/OFFSET:限制返回的行数。

存储引擎

❓执行一条 SQL 的全过程

MySQL 存储引擎有什么?

  1. InnoDB:MySQL 默认引擎,支持行级锁和事务
  2. MyISAM:不支持事务,只有表锁。适合读多写少
  3. Memory:存储在内存中,读写较快,但没有持久化

MyISAM 和 InnoDB 有什么区别?

  1. InnoDB 支持行级锁和事务,MyISAM 只有表锁,没有事务。
  2. InnoDB 将索引和数据存放在一起,B+ 树叶子结点存放数据;MyISAM 将索引和数据分开存储,B+ 树中存放数据地址。

❓哪个存储引擎的 count(*) 最快?

NULL 值是怎么存储的?

MySQL 每一行有 NULL 值列表,通过二进制标记为 NULL 值的列。

char 和 varchar 的区别

  • char 是定长字符串,会使用空格填充
  • varchar 是可变字符串,只存储实际占用和字符串长度

假如说一个字段是varchar(10),但它其实只有6个字节,那它在内存中占的存储空间是多少?在文件中占的存储空间是多少?

  1. 内存:10 字节。按照最大值分配内存
  2. 存储:6 字节 + 记录字符串长度的 1-2 字节

如果内存超大,MySQL 能代替 Redis 吗?

不能。

  1. MySQL 是为了磁盘存储而设计,优化主要为了减少磁盘 IO 的读写性能;Redis 是面向内存设计的数据库。
  2. MySQL 的所有数据结构都是 B+ 树,复杂度是 O(logn);Redis 具有多种数据结构,Hash 复杂度 O(1)。
  3. MySQL 更新为了保证事物隔离,需要加锁;Redis 更新不需要加锁。

索引结构

MySQL 索引有哪些?

  1. B+ 树索引:InnoDB 的默认索引
  2. 哈希索引
  3. 全文索引

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

B+ 树索引

为什么使用 B+ 树?

  1. B+ 树是多叉树,平衡二叉树、红黑树是二叉树,层级更高,且需要频繁进行平衡,需要更多磁盘 IO
  2. 跳表的性能不稳定,极端情况会变成链表,且占用空间较大,需要多次磁盘 IO
  3. B 树所有节点都存放数据,B+ 树只有叶子节点才存放数据,对范围查询不友好,且读取索引时需要更多的内存和磁盘 IO。
  4. 哈希表不支持范围查询和排序

聚簇索引和非聚簇索引的区别?

  • 聚簇索引通常是主键索引,叶子节点存放数据。
  • 非聚簇索引通常是非主键的索引,叶子结点存放主键,需要回表查询。

❓insert 操作对 B+ 树结构的改变是怎么样的?

❓假如一张表有两千万的数据,B+树的高度是多少?怎么算的?

索引应用

MySQL 有什么索引?

  1. 主键索引
  2. 唯一索引
  3. 普通索引
  4. 联合索引:多字段联合查询
  5. 前缀索引:字符串前缀匹配

普通索引和唯一索引有什么区别?哪个更新性能更好?

普通索引的值可以重复,唯一索引的值具有唯一约束,不能重复。

普通索引性能更好。

普通索引更新完直接放在 change buffer 缓冲区;唯一索引需要磁盘 IO 验证唯一约束。

主键怎么设置?假如你不设置会怎么样?

设置列名后设置 primary key

不设置主键会使用第一个非 NULL 且唯一的列作为主键,如不存在会生成隐式 rowid 列作为主键。

为什么需要创建索引?

  1. 将全表扫描的 O(n) 优化成 B+ 树的 O(logn)
  2. 将随机 IO 转化成顺序 IO
  3. 索引可以帮助 MySQL 避免外部排序和使用临时表

除了索引,还能怎么优化数据库?

  1. 对频繁被查询的条件添加索引
  2. 避免使用 select *,尽量使用具体列名
  3. 使用分页
  4. 对于大量添加、更新或删除,使用批量处理优化
  5. 查询时避免使用函数

选择什么字段作为索引?

  1. 值的重复性较低、NULL 值较少
  2. 常作为条件查询、分组、排序

索引越多越好吗?

不是的。

  1. 索引占用空间,每个索引都有独立的 B+ 树。
  2. 更新和插入需要维护所有 B+ 树,降低写入性能。

什么情况不用索引更好?

  1. 写多读少
  2. 值的重复度高

❓索引怎么优化?

建立了索引一定会被用到吗?

  1. 索引失效:联合索引不满足最左匹配原则、非等的范围查询、使用函数或隐性转换、左侧模糊查询、两侧不全是索引时使用 or
  2. 数据库优化:因为索引是用来索引少量数据的,如果通过索引查询返回大批量的数据,则还不如全表扫描方便,此时索引就会失效。

纯数字的字符串不加引号会命中索引吗?

不会。会进行使用函数隐式转换,索引失效。

MySQL 8 的索引新特性

  1. 函数索引:解决函数会导致索引失效的问题
  2. 索引跳跃式扫描:不满足最左匹配原则也可以使用联合索引

建立联合索引有什么需要注意的?

将区分度大的字段放在最左侧

❓了解索引下推吗?什么情况下会下推到引擎去处理?

如果查询条件中包含索引列和非索引列,具体查询流程是什么样的?

先在索引列拿到主键 id,再回表过滤非索引列。

事务

MySQL 事务有什么特性?

  1. 原子性:undo log
  2. 一致性
  3. 隔离性:MVCC + 锁
  4. 持久性:redo log

事物的隔离性怎么保证?

事物的原子性怎么保证?

事物的持久性怎么保证?

MySQL 事物和 Redis 事物的区别?

MySQL事务隔离级别有哪些?分别解决哪些问题?

脏读和幻读的区别

MySQL 默认隔离级别是什么?怎么实现的?

什么是 MVCC?

MVCC 如何判断行记录对某一个事务是否可见

读已提交和可重复读隔离级别实现MVCC的区别?

为什么互联网公司用读已提交隔离级别?

可重复读隔离级别是如何解决不可重复读的?

可重复读隔离级别是怎么解决么幻读的?

可重复读隔离级别解决了什么问题?有没有完全解决么幻读?

可重复读隔离级别为什么不能完全避免么幻读?什么情况下出现么幻读?

可重复读隔离级别,MVCC完全解决了不可重复读问题吗?

Released under the MIT License.