Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

  • MySQL 类

    • MySQL 为什么一定要有一个主键
    • MySQL 中的 RR 隔离级别,到底有没有解决幻读问题
    • MySQL 的行级锁到底锁的是什么东西?
    • 存储 MD5 值应该用 VARCHAR 还是用 CHAR?
    • 数据库的三范式是什么?
    • 说说 InnoDB 与 MyISAM 的区别
    • drop、truncate、delete 的区别
    • 聊一聊数据库事务机制
    • 聊一聊 MySQL 中的关联查询
    • 事务隔离级别有哪些?MySQL 的默认隔离级别是什么
    • 分库分表之后,id 主键如何处理?
    • 说说在 MySQL 中一条查询 SQL 是如何执行的?
      • 讲解下 DDL、DML、DCL
      • 存储过程和触发器的作用
      • MySQL 如何行转列和列转行
      • 如何查看 SQL 的执行计划
      • union 和 unionAll 的区别
      • having 和 where 的区别
      • 常见的索引原则
      • MySQL 中的 IN 和 EXISTS 子句有什么区别?
      • MySQL 如何处理 NULL 值,对性能有什么影响?
      • 如何在 MySQL 中处理和避免全表扫描?
      • MySQL 中的表空间是什么,它的作用是什么?
      • 在 MySQL 中,如何优化 ORDER BY 查询?
    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • MySQL 类
    刘博
    2025-12-29
    目录

    说说在 MySQL 中一条查询 SQL 是如何执行的?

    MySQL 执行一条查询 SQL 的流程分为 “客户端与服务器交互、服务器层处理、存储引擎层处理” 三个阶段,核心涉及连接器、查询缓存、分析器、优化器、执行器、存储引擎等组件,具体流程如下:

    # 1. 阶段 1:客户端与服务器建立连接(连接器)

    • 客户端通过 TCP/IP 协议与 MySQL 服务器建立连接,连接器验证用户名、密码(如root用户的密码),并分配权限(如该用户是否有查询某表的权限);
    • 连接建立后,若客户端长时间无操作,连接器会自动断开连接(默认超时时间由wait_timeout参数控制,默认 8 小时);
    • 核心作用:身份验证、权限分配、维持连接。

    # 2. 阶段 2:查询缓存(MySQL 8.0 已移除)

    • 若 MySQL 开启查询缓存(query_cache_type=ON),服务器会先检查查询 SQL 是否在缓存中(缓存以 “SQL 语句” 为 key,查询结果为 value);
    • 若缓存命中(SQL 完全一致,区分大小写和空格),直接返回缓存结果,跳过后续分析、优化步骤;
    • 若缓存未命中,继续执行后续流程;
    • 核心问题:查询缓存失效频繁(如表数据更新时,该表的所有缓存都会失效),MySQL 8.0 已移除该功能,推荐用 Redis 实现应用层缓存。

    # 3. 阶段 3:SQL 解析(分析器)

    • 词法分析:将 SQL 语句拆分为 “Token”(如关键字SELECT、表名user、字段名name、条件age>20);
    • 语法分析:根据 MySQL 语法规则,检查 SQL 语句的合法性(如SELECT是否拼写错误、WHERE子句是否缺少条件),生成 “抽象语法树(AST)”;
    • 核心作用:验证 SQL 语法正确性,将 SQL 转换为机器可识别的语法结构。

    # 4. 阶段 4:SQL 优化(优化器)

    • 优化器的核心作用:在多个执行方案中选择 “成本最低” 的方案(成本包括 CPU 消耗、IO 消耗等);
    • 主要优化操作:
      • 选择索引:根据表统计信息(如索引 cardinality、数据分布),选择最优索引(如选择idx_age而非全表扫描);
      • 调整关联顺序:多表关联时,选择小表作为驱动表(如user表和order表关联,选择行数少的表作为驱动表);
      • 简化表达式:如1+2=3优化为3,WHERE id=1 AND id=2优化为WHERE 1=2(恒假条件);
      • 改写 SQL:如IN (1,2,3)改写为OR条件,LEFT JOIN优化为INNER JOIN(若条件允许);
    • 输出结果:生成 “执行计划”(可通过EXPLAIN命令查看,包含索引选择、关联顺序、扫描行数等信息)。

    # 5. 阶段 5:SQL 执行(执行器)

    • 执行器根据执行计划,调用存储引擎(如 InnoDB)的 API 执行查询:
      • 权限校验:再次校验用户是否有查询表字段的权限(避免优化器阶段权限变更);
      • 数据读取:根据执行计划,通过存储引擎读取数据(如通过索引idx_age定位age>20的行,逐行返回);
      • 结果处理:将读取的数据按 SQL 要求过滤、排序(ORDER BY)、分页(LIMIT),最终生成结果集;
    • 核心作用:协调存储引擎执行查询,处理结果集。

    # 6. 阶段 6:存储引擎层处理(如 InnoDB)

    • 存储引擎负责数据的物理存储和读取,接收执行器的指令(如 “读取user表中age>20的行”);
    • 若使用索引查询,InnoDB 通过聚簇索引或非聚簇索引定位数据(非聚簇索引需回表查询完整行数据);
    • 若未使用索引,InnoDB 执行全表扫描(逐行读取数据,判断是否满足条件);
    • 核心作用:提供数据的物理存储、索引访问、事务支持等底层能力。

    # 总结流程

    客户端连接 → (查询缓存,已移除) → 解析 SQL(分析器) → 优化 SQL(优化器) → 执行 SQL(执行器) → 存储引擎读取数据 → 返回结果集。


    上次更新: 12/30/2025
    分库分表之后,id 主键如何处理?
    讲解下 DDL、DML、DCL

    ← 分库分表之后,id 主键如何处理? 讲解下 DDL、DML、DCL→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式