当前位置: 首页 > news >正文

【MySQL】最左前缀匹配原则

 

目录

准备库表

结果集在索引列中的查询

1. explain select a,b,c from t where a=1;

2. explain select a,b,c from t where a=1 AND b=2;

3. explain select a,b,c from t where a=1 order by b;

4. explain select a,b,c from t where a=1 order by d;

5. explain select a,b,c from t where b=1;

结果集不在索引列中的查询

1. explain select a,b,c,d from t where a=1;

2. explain select a,b,c,d from t where a=1 AND b=2;

3. explain select a,b,c,d from t where a=1 order by b; 

4. explain select a,b,c,d from t where a=1 order by d;

5. explain select a,b,c,d from t where b=1;

总结


MySQL 版本:8.0.32

通过实战的方式加深对最左前缀匹配原则的理解

准备库表

CREATE TABLE `t` (`id` int unsigned NOT NULL AUTO_INCREMENT,`a` int NOT NULL DEFAULT '0',`b` int NOT NULL DEFAULT '0',`c` int NOT NULL DEFAULT '0',`d` int DEFAULT NULL,PRIMARY KEY (`id`),KEY `key_a_b_c` (`a`,`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

建立联合索引(a,b,c)

结果集在索引列中的查询

1. explain select a,b,c from t where a=1;

type: ref 表示走普通索引,结果可能有多行

key_len: 4 表示只用到联合索引(a,b,c)的最左前缀 a

Extra: Using index 表示走覆盖索引,不用回表

2. explain select a,b,c from t where a=1 AND b=2;

和 1 差不多,只不过 key_len 是 8,表示用到联合索引(a,b,c)的两个最左前缀 a,b

3. explain select a,b,c from t where a=1 order by b;

和 1 完全相同,因为建立联合索引(a,b,c)后,找到 a 对应的索引列,那么 b 本身就是有序的

4. explain select a,b,c from t where a=1 order by d;

因为使用了索引列之外的列进行排序,所以走了 Using filesort 外部排序

order by 的排序原理是 MySQL 会给每个线程分配一块内存用于排序,称为 sort_buffer,这里会按照 a 索引列匹配,因为 d 在主键索引中,所以回表查出整行,存入 sort_buffer 中,最后对 sort_buffer 中的数据按照字段 d 做快速排序,而排序这个动作可能在内存中完成,也可能需要使用外部排序,因此可能会有性能问题

5. explain select a,b,c from t where b=1;

type: index,因为最左前缀匹配原则,没有命中索引,但因为查询的列都在联合索引列中,走了索引扫描

Extra: Using where; Using index 表示条件过滤,且走了覆盖索引

结果集不在索引列中的查询

1. explain select a,b,c,d from t where a=1;

和只查 a,b,c 唯一的区别是 Extra 列为空,因为查 d 需要回表

2. explain select a,b,c,d from t where a=1 AND b=2;

和只查 a,b,c 唯一的区别是 Extra 列为空,因为查 d 需要回表

3. explain select a,b,c,d from t where a=1 order by b; 

和只查 a,b,c 唯一的区别是 Extra 列为空,因为查 d 需要回表

4. explain select a,b,c,d from t where a=1 order by d;

和只查 a,b,c 完全相同,因为排序字段也会放在 sort_buffer 中

5. explain select a,b,c,d from t where b=1;

type:ALL,因为 d 不在索引列中,索引失效,直接走了全表扫描

Extra:Using Where,按条件过滤

总结

对于结果集在和不在索引列的两种情况,虽然都不符合最左前缀原则,执行计划还是有很大区别的

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • zdppy+vue3+onllyoffice开发文档管理系统项目实战 20240808 上课笔记
  • Java中的分布式日志与追踪
  • Postman Pre-request Script
  • 【Vue3】Pinia存储及读取数据
  • [Meachines] [Easy] valentine SSL心脏滴血+SSH-RSA解密+trp00f自动化权限提升+Tmux进程劫持权限提升
  • 07、MySQL-多表查询
  • 关于重复提交
  • k8s—Prometheus+Grafana+Altermaneger构建监控平台
  • 2024年软件测试八股文(含答案+文档)
  • Qwen2-7b+AnythingLLM+ollama 部署API调用
  • Linux 进程概念
  • 高效清理优化工具 Sonoma Cache Cleaner mac 19.0.6注册激活版
  • PCIe学习笔记(20)
  • FFmpeg音频重采样基本流程
  • 代码随想录第34天|动态规划
  • ----------
  • 【刷算法】从上往下打印二叉树
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • ESLint简单操作
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • SpiderData 2019年2月13日 DApp数据排行榜
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • XForms - 更强大的Form
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 记录:CentOS7.2配置LNMP环境记录
  • 解析 Webpack中import、require、按需加载的执行过程
  • 前端性能优化--懒加载和预加载
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 使用 QuickBI 搭建酷炫可视化分析
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 微信开源mars源码分析1—上层samples分析
  • 我是如何设计 Upload 上传组件的
  • 源码安装memcached和php memcache扩展
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Nginx实现动静分离
  • scrapy中间件源码分析及常用中间件大全
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • #android不同版本废弃api,新api。
  • #微信小程序:微信小程序常见的配置传旨
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (04)odoo视图操作
  • (1)(1.11) SiK Radio v2(一)
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (算法)N皇后问题
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一) storm的集群安装与配置
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • ***利用Ms05002溢出找“肉鸡
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...