Bootstrap

mysql面试题

一、基础概念

  1. 什么是主键(Primary Key)?
    答案: 唯一标识表中每行数据的字段或字段组合,不允许 NULL 值,确保数据唯一性。

  2. 外键(Foreign Key)的作用是什么?
    答案: 建立表间关联,确保引用完整性。外键字段值必须存在于被引用表的主键中。

  3. CHAR 和 VARCHAR 的区别?
    答案:

    • CHAR 定长,存储效率高,适合固定长度(如身份证号)。
    • VARCHAR 变长,节省空间,适合长度变化大的数据(如地址)。
  4. MySQL 的默认存储引擎是什么?
    答案: InnoDB(MySQL 5.5+ 后默认)。

  5. 主键(Primary Key)与唯一键(Unique Key)的区别?
    答案:

    • 主键唯一标识表中每行数据,不允许 NULL,一个表只能有一个主键。
    • 唯一键确保列值唯一,允许 NULL,一个表可以有多个唯一键。
  6. InnoDB 和 MyISAM 的区别?
    答案:

    • 事务:InnoDB 支持事务,MyISAM 不支持。
    • 锁粒度:InnoDB 支持行级锁,MyISAM 仅支持表级锁。
    • 索引结构:InnoDB 主键索引为聚簇索引,数据与索引存储在一起;MyISAM 为非聚簇索引,数据与索引分离。

二、SQL 语句

  1. 如何查询表中不重复的记录?
    答案:

    SELECT DISTINCT column_name FROM table;
    
  2. LIMIT 和 OFFSET 的作用?
    答案:

    SELECT * FROM table LIMIT 10 OFFSET 20; -- 跳过前20条,取10条
    
  3. 如何删除表中所有数据?
    答案:

    TRUNCATE TABLE table_name; -- 快速清空,不记录日志
    DELETE FROM table_name;     -- 逐行删除,可回滚
    
  4. 如何优化 SELECT COUNT(*) 查询?
    答案:

    • MyISAM 直接读取表元数据的行数统计。
    • InnoDB 需遍历索引或使用近似值(如 EXPLAIN 估算)。
  5. 如何优化大分页查询(如 LIMIT 1000000,10)?
    答案:
    使用延迟关联:

    SELECT * FROM users WHERE id >= (SELECT id FROM users ORDER BY id LIMIT 1000000,1) LIMIT 10;  
    

    减少回表次数。

  6. LEFT JOIN、INNER JOIN 和 RIGHT JOIN 的区别?
    答案:

    • LEFT JOIN:返回左表所有行,右表无匹配则填充 NULL。
    • INNER JOIN:仅返回两表匹配的行。
    • RIGHT JOIN:返回右表所有行,左表无匹配则填充 NULL。

三、索引

  1. 索引的优缺点?
    答案:

    • 优点: 加速查询、唯一约束。
    • 缺点: 占用空间、降低写操作速度(需维护索引)。
  2. 什么情况下索引会失效?
    答案:

    • 使用 LIKE '%abc'
    • 对字段进行函数操作(如 WHERE YEAR(date) = 2023
    • 类型转换(如字符串字段用数字查询)
  3. B+树索引和哈希索引的区别?
    答案:

    • B+树: 支持范围查询、排序,适用于磁盘存储。
    • 哈希索引: 精确查找快,不支持范围查询。
  4. 索引类型与结构

    • B+树索引:InnoDB 默认,支持范围查询,叶子节点存储数据或主键。
    • 哈希索引:仅 MEMORY 引擎支持,适合精确查找。
    • 联合索引:遵循最左前缀原则(如 INDEX(a, b) 无法单独使用 b 查询)。
  5. 索引失效场景

    • 对字段使用函数(如 YEAR(date))或类型转换。
    • LIKE '%abc' 左模糊查询。
    • OR 条件未全索引、组合索引未用第一列。
  6. 什么是最左前缀匹配原则?
    答案:
    组合索引中,查询条件需从最左列开始匹配。例如索引 (a,b,c)WHERE a=1 AND b=2 可用索引,但 WHERE b=2 不可用。

  7. 覆盖索引是什么?如何优化查询?
    答案:
    索引包含查询所需的所有字段,避免回表。例如,若索引包含 (age, name),查询 SELECT name FROM users WHERE age=25 可直接通过索引获取数据。

  8. 分页查询优化

    • 延迟关联:先查主键再关联,减少回表次数。
    SELECT * FROM users WHERE id >= (SELECT id FROM users ORDER BY id LIMIT 1000000, 1) LIMIT 10;
    
  9. 为什么要用小表驱动大表?
    在 MySQL 中,“小表驱动大表”是一种优化 JOIN 操作的常见策略,其核心目的是减少外层循环次数,从而降低整体查询的计算量和 I/O 开销。以下是详细解释:

    嵌套循环连接(Nested-Loop Join)的工作原理
    MySQL 默认使用嵌套循环算法执行 JOIN 操作,流程如下:

    驱动表(外层表):首先被访问的表,假设有 N 行。

    被驱动表(内层表):随后被访问的表,假设有 M 行。

    操作步骤:

    遍历驱动表的每一行。

    对驱动表的每一行,遍历被驱动表的所有行(或通过索引查找匹配的行)。

    若被驱动表有索引,每次内层循环的时间复杂度近似为 O(1);若无索引,则为 O(M)。

  • 小表驱动大表的核心是减少外层循环次数,显著降低计算量。

  • 索引是优化的前提条件,尤其是被驱动表的 JOIN 字段必须建立索引。

  • 通过 EXPLAIN 分析执行计划,验证驱动表选择和索引使用是否合理。

17. mysql 索引查找数据大概需要多少次io操作?树的高度怎么算?

B+ 树索引的结构
MySQL 的索引默认使用 B+ 树结构,特点如下:

树的高度:通常为 3~4 层(极端场景可能更高)。

- 节点容量:

每个节点存储多个键值(Key)和指针(Pointer)。

假设一个页(Page)大小为 16KB,单个索引键(如 BIGINT)占 8 字节,指针占 6 字节,则:

单个节点可存储的键值数量:16KB / (8B + 6B) ≈ 1170 个。

若叶子节点存储完整数据行(聚集索引),假设每行数据 1KB,则:
单个叶子节点可存储的行数:16KB / 1KB = 16 行。

- 索引层高
层高越低,I/O 越少:

若单表数据量为 N,树高计算公式:h ≈ log(N) / log(节点容量)。

示例:

节点容量 1170,叶子节点容量 16。

3 层 B+ 树可支撑的数据量:1170 × 1170 × 16 ≈ 21,902,400 行。

4 层 B+ 树可支撑:1170^3 × 16 ≈ 25.6 亿行。

四、事务与锁

  1. ACID 是什么?
    答案:

    • 原子性(Atomicity): 事务全部成功或全部失败。
    • 隔离性(Isolation): 事务间互不干扰。
    • 持久性(Durability): 事务提交后数据永久保存。
    • 一致性(Consistency): 数据符合约束规则。
  2. 事务隔离级别有哪些?
    答案:

    • READ UNCOMMITTED(可能脏读)
    • READ COMMITTED(解决脏读)
    • REPEATABLE READ(MySQL 默认,解决不可重复读)
    • SERIALIZABLE(完全隔离,性能低)
  3. 什么是死锁?如何避免?
    答案: 多个事务互相等待对方释放锁。
    避免方法: 按顺序访问资源、减小事务粒度、设置超时。

  4. 锁的类型与死锁处理

    • 行级锁:InnoDB 支持,并发度高但可能死锁。
    • 表级锁:MyISAM 使用,开销小但并发度低。
    • 避免死锁:按顺序访问资源、设置事务超时、启用死锁检测。
  5. InnoDB 如何通过 MVCC 实现可重复读?
    答案:
    通过隐藏的事务版本号和 Read View 实现多版本控制。事务启动时生成一致性视图,读取数据时根据版本号判断可见性。


五、性能优化

  1. EXPLAIN 的作用?
    答案: 分析 SQL 执行计划,查看是否使用索引、扫描行数等。

  2. 如何优化慢查询?
    答案:

    • 添加索引
    • 避免 SELECT *,只查必要字段
    • 分库分表
    • 优化 SQL 结构(如减少子查询)
  3. 什么是覆盖索引?
    答案: 索引包含查询所需的所有字段,无需回表查询数据行。

  4. 慢查询优化

    • 使用 EXPLAIN 分析执行计划,关注 type(访问类型)和 key(使用索引)。
    • 避免 SELECT *、减少子查询、添加覆盖索引。
  5. 分库分表策略

    • 垂直分库:按业务拆分(如用户库、订单库)。
    • 水平分表:按规则分散数据(如按用户 ID 哈希)。
    • 分布式事务:使用 2PC、TCC 或本地消息表保障一致性。
  6. 备份与恢复

    • mysqldump:逻辑备份,适合小数据量。
    • XtraBackup:物理备份,支持热备份与增量备份。

六、高可用与架构

  1. 主从复制的原理及配置步骤?
    答案:

    • 原理:主库写 Binlog,从库通过 I/O 线程读取并写入 Relay Log,SQL 线程重放日志同步数据。
    • 步骤:主库开启 Binlog,从库配置主库信息并启动复制。
  2. 分库分表的常见方案?
    答案:

    • 水平分表: 按数据行拆分(如按用户 ID 哈希)。
    • 垂直分表: 按列拆分(将常用字段与不常用字段分开)。

七、高级特性

  1. 什么是窗口函数?举例说明。
    答案:

    SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank FROM employees;
    
  2. JSON 类型字段如何查询?
    答案:

    SELECT * FROM table WHERE JSON_EXTRACT(data, '$.key') = 'value';
    
;