sql执行流程经典案例分析

现在有联合索引(a,b),select* form tb where b =xx group by a执行流程是什么样子的?

sql 复制代码
CREATE TABLE IF NOT EXISTS `test`(
  `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT'主键',
  `a` INT(10) NULL,
  `b` INT(10) NULL,
   PRIMARY KEY(id),
   INDEX idx_a_b(a,b)
   )ENGINE = INNODB;
   INSERT INTO `test`(a,b) VALUES(2,3);
   INSERT INTO `test`(a,b) VALUES(2,4);
   INSERT INTO `test`(a,b) VALUES(2,5);
   INSERT INTO `test`(a,b) VALUES(2,6);
   INSERT INTO `test`(a,b) VALUES(2,7);
    INSERT INTO `test`(a,b) VALUES(3,3);
   INSERT INTO `test`(a,b) VALUES(3,4);
    INSERT INTO `test`(a,b) VALUES(4,3);
   INSERT INTO `test`(a,b) VALUES(4,4);
   
   EXPLAIN SELECT * FROM `test` WHERE b = 3 GROUP BY a = 3;

首先是根据b查询,而a和b构建了联合索引,不满足最左匹配原则,不一定会走联合索引,如果查询优化器发现全表扫描的效率低于扫描联合索引的效率的话,就会走联合索引,但是因为不满足最左匹配原则,因此一定会把整个索引树都扫描一遍,取出b = xx的情况, 由于索引 (a, b) 已经按 a 排序,因此可以有效地使用索引顺序扫描 来快速对 a 列进行分组。然后根据b取出对应的主键id,进行回表,拿到所有的数据后,创建一个临时的表来存储按a分组的数据,最终返回结果集。

如果查询优化器发现全表扫描的效率高于扫描联合索引的效率的话,就不会走索引,直接进行全表扫描,查询b=xx的记录,然后将所有记录按a进行分组存入临时表中,返回结果集。

explain执行计划:

执行流程总结(全表扫描索引的情况):

  1. 扫描联合索引 (a, b):MySQL 根据联合索引 (a, b) 找到 b = xx 的所有记录。
  2. a****进行分组 :由于联合索引 (a, b) 中的 a 已经排序,MySQL 可以直接根据 a 进行 GROUP BY 操作。
  3. 是否需要回表
    • 如果查询的列全部包含在联合索引中(如 SELECT a, b),则不需要回表。
    • 如果查询需要访问其他列(如 SELECT *),则 MySQL 需要回表,从表中读取完整数据。
  1. 返回结果集:将查询结果返回给客户端。

执行流程总结(全表扫描原数据表的情况):

  1. 全表扫描
    • MySQL 扫描原始数据表,逐行检查 b 列是否满足 b = xx 的条件。
    • 将符合 b = xx 的记录提取出来。
  1. 放入临时表
    • 将符合条件的记录放入临时表中(如果数据量较大且无法在内存中处理时)。
  1. 根据 a****进行分组
    • 在临时表中对 a 列进行 GROUP BY 操作,按 a 分组。
  1. 返回结果
    • MySQL 将分组后的结果返回给用户。
相关推荐
TDengine (老段)7 分钟前
TDengine 数学函数 FLOOR 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
大气层煮月亮1 小时前
Oracle EBS ERP开发——报表生成Excel标准模板设计
数据库·oracle·excel
云和数据.ChenGuang1 小时前
达梦数据库的命名空间
数据库·oracle
三三木木七2 小时前
mysql拒绝连接
数据库·mysql
蹦跶的小羊羔2 小时前
sql数据库语法
数据库·sql
唐古乌梁海2 小时前
【mysql】InnoDB的聚簇索引和非聚簇索引工作原理
数据库·mysql
我变秃了也没变强2 小时前
pgsql配置密码复杂度策略
数据库·postgresql
PawSQL2 小时前
企业级SQL审核工具PawSQL介绍(1) - 六大核心能力
数据库·sql·oracle
幼稚园的山代王2 小时前
NoSQL介绍
数据库·nosql
猫林老师2 小时前
HarmonyOS线程模型与性能优化实战
数据库·分布式·harmonyos