MySql 组合索引的使用

news2024/11/20 11:39:08

MySql 组合索引的使用

测试Mysql组合索引在不同的查询条件组合下的索引使用情况。当有a+b+c 3个字的的组合索引时,按照MySql 的左匹配原则,a+b+c,a+b,a 是满足左匹配原则,肯定是会走索引的,但是其他的场景,比如a+c, b+c, b+a, b+a+c 等是否仍会走索引呢?

测试环境

MySql 5.7

测试表:

CREATE TABLE `report_user_achievement` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_id` int(11) NOT NULL COMMENT '用户id',
  `user_name` varchar(128) DEFAULT NULL COMMENT '用户名称',
  `is_inner` tinyint(1) NOT NULL COMMENT '是否为内部',
  `year` int(11) NOT NULL COMMENT '年',
  `month` int(11) NOT NULL COMMENT '月',
  `week_of_month` int(11) NOT NULL COMMENT '周(本月)',
  `date_time` datetime(6) NOT NULL COMMENT '日期',
  `achievement_amount` decimal(11,2) DEFAULT NULL COMMENT '业绩金额',
  `last_business_date_time` datetime(6) DEFAULT NULL COMMENT '最近的业务时间',
  PRIMARY KEY (`id`),
  KEY `idx__user_id__date_time__is_inner` (`user_id`,`date_time`,`is_inner`) COMMENT ''
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户报表-业绩表'

测试

测试肯定走索引的场景

a+b+c,a+b,a

EXPLAIN
SELECT * FROM `report_user_expert_network_achievement` WHERE user_id = 56;  

EXPLAIN
SELECT * FROM `report_user_expert_network_achievement` WHERE user_id = 56 AND date_time = '2023-12-07 00:00:00.000000';  

EXPLAIN
SELECT * FROM `report_user_expert_network_achievement` WHERE user_id = 56 AND date_time = '2023-12-07 00:00:00.000000' AND is_inner = FALSE;  

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

EXPLAIN 结果三条记录都是走索引

测试肯定不走索引的场景

b, c, b+c,c+b

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE date_time = '2023-12-07 00:00:00.000000' ; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE is_inner = FALSE;  #ALL Using where

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE date_time = '2023-12-07 00:00:00.000000' AND is_inner = FALSE; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE is_inner = FALSE AND date_time = '2023-12-07 00:00:00.000000';

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

EXPLAIN 结果都是ALL 走了全表扫描,没有走索引。

测试可能会走索引的场景

由于Mysql 会对查询条件进行优化,即使没有按照索引的顺序的查询语句,也会按照索引进行优化。例如:b+a+c, b+c+a, c+a+b, c+b+a, b+a

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE date_time = '2023-12-07 00:00:00.000000' AND user_id = 56 AND is_inner = FALSE; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE date_time = '2023-12-07 00:00:00.000000' AND is_inner = FALSE AND user_id = 56 ; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE is_inner = FALSE AND user_id = 56 AND date_time = '2023-12-07 00:00:00.000000'; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE is_inner = FALSE AND date_time = '2023-12-07 00:00:00.000000' AND user_id = 56 ; 

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE date_time = '2023-12-07 00:00:00.000000' AND user_id = 56; 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

EXPLAIN 结果记录都是走索引,说明Where 语句中条件顺序不影响是否走索引。

测试索引下推

对于a+c,c+a 这组合,不完全满足左匹配,但又可以通过索引优化的组合。

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE user_id = 56 AND is_inner = FALSE;  

EXPLAIN
SELECT * FROM `report_user_achievement` WHERE is_inner = FALSE AND user_id = 56; 

在这里插入图片描述
在这里插入图片描述

测试结果是仍然走了索引,但和完全走索引不同的是Extra 字段多了Using index condition
原因是索引下推 这个MySql 5.7 正式完全支持的功能,

这是一段GPT 对索引下推的描述:

MySQL的索引下推(Index Condition Pushdown,简称ICP)是一个优化查询执行的特性,它允许MySQL在查询过程中更高效地利用复合索引。在没有索引下推的情况下,MySQL会根据索引快速定位到满足条件的记录,然后再回表读取完整的行数据,接着在服务器层面对这些数据进行条件过滤。
索引下推优化则是在获取索引的同时,将那些可以由索引中的列来评估的过滤条件推送到存储引擎层。这样,存储引擎在利用索引查找记录的同时,就可以对索引中的列进行条件过滤,只有满足条件的记录才会被读取并返回给服务器层。这样可以减少不必要的回表操作和数据传输,从而提高查询的效率。
索引下推适用于以下情况:

  • 查询使用了复合索引。
  • 查询条件中包含了索引列的部分或全部列的条件。
  • 存储引擎支持索引下推(InnoDB和MyISAM支持,而Memory存储引擎不支持)。

总结就是因为a+c 这个条件是可以在索引上直接进行过滤的,因此可以先通过索引过滤,再去回表去数据,从而提高效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1500455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PCL】(二十六)自定义条件的欧几里得聚类分割点云

&#xff08;二十六&#xff09;自定义条件的欧几里得聚类分割点云 以下代码实现自定义条件对点进行欧几里得聚类分割。 conditional_euclidean_clustering.cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/console/time.h>#…

鞋服品牌怎样合理把控订货深度和宽度

在鞋服品牌的运营管理中&#xff0c;订货深度和宽度是两个至关重要的概念。订货深度指的是某一款式或规格的产品数量&#xff0c;而订货宽度则代表品牌所涵盖的产品种类和款式。合理把控订货深度和宽度对于品牌的库存管理、销售情况以及顾客满意度都有着深远的影响。本文将探讨…

【Linux】 yum —— Linux 的软件包管理器

Linux 的软件包管理器 yum yum 是什么什么是软件包查看软件包 yum 命令行工具yum 配置文件yum 凭什么可以支持下载呢&#xff1f;yum 生态yum 社区yum 的故障排除和资源支持yum 的持续集成和持续交付 yum 是什么 Yum&#xff08;Yellowdog Updater Modified&#xff09;是一个…

洛谷 P8816 [CSP-J 2022] 上升点列(T4)

目录 题目传送门 算法解析 最终代码 提交结果 尾声 题目传送门 [CSP-J 2022] 上升点列 - 洛谷https://www.luogu.com.cn/problem/P8816 算法解析 k 0 且 xi, yi 值域不大时&#xff0c;这题是非常简单的 DP&#xff0c;类似「数字三角形」。 记 dp(x,y) 为「以 (x,y) …

GaussDB(DWS)运维利刃:TopSQL工具解析

在生产环境中&#xff0c;难免会面临查询语句出现异常中断、阻塞时间长等突发问题&#xff0c;如果没能及时记录信息&#xff0c;事后就需要投入更多的人力及时间成本进行问题的定位和解决&#xff0c;有时还无法定位到错误出现的地方。在本期《GaussDB(DWS)运维利刃&#xff1…

Dubbo基础入门二

8、Dubbo协议 服务调用 8.1 服务端 启动过程深入分析 我们查看一下服务启动的过程 ProtocolFilterWrapper.export 好我们进入DubboProtocol.export 创建服务 分析我们的Handler 我们接着返回刚才位置 下面的super方法里面会创建服务&#xff0c;ChannelHandlers.wrap会对hand…

套接字编程 --- 一

目录 1. 预备知识 1.1. 端口号 1.2. 认识TCP协议 1.3. 认识UDP协议 1.4. 网络字节序 2. socket 2.1. socket 常见系统调用 2.1.1. socket 系统调用 2.1.2. bind 系统调用 2.1.3. recvfrom 系统调用 2.1.4. sendto系统调用 2.3. 其他相关接口 2.3.1. bzero 2.3.2…

代码随想录算法训练营第day10|232.用栈实现队列、 225. 用队列实现栈

目录 a.232.用栈实现队列 b. 225. 用队列实现栈 a.232.用栈实现队列 题目链接 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素…

专题一 - 双指针 - leetcode 202. 快乐数 | 简单难度

leetcode 202. 快乐数 leetcode 202. 快乐数 | 简单难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 202. 快乐数 | 简单难度 1. 题目详情 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」…

掼蛋的牌型与规律(上篇)

掼蛋是一项配合类的棋牌竞技游戏&#xff0c;掼蛋的最大魅力以及最集中的特点在于变化&#xff0c;在于组牌的变数。有的掼蛋新手往往先把牌配死&#xff0c;并且直接决定好出牌计划&#xff0c;然后守株待兔。掼蛋的取胜之道在于静态组合加上动态变化。本文主要介绍一下掼蛋的…

【广度优先搜索】【图论】【并集查找】2493. 将节点分成尽可能多的组

作者推荐 视频算法专题 本文涉及知识点 广度优先搜索 图论 并集查找 LeetCod2493. 将节点分成尽可能多的组 给你一个正整数 n &#xff0c;表示一个 无向 图中的节点数目&#xff0c;节点编号从 1 到 n 。 同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai…

神州大地人类来源猜想

在公元前2000年以前&#xff0c;伟大的中华民族还是石器时代&#xff0c;我们有很多美好的神话和传说&#xff0c;三皇五帝就是这个时代伟大部落或者部落首领的故事。 关于人类的历史&#xff0c;从基因学上最新的研究成果大概是这样的&#xff0c;虽然从300万年前就诞生了人类…

3D资产管理

3D 资产管理是指组织、跟踪、优化和分发 3D 模型和资产以用于游戏、电影、AR/VR 体验等各种应用的过程。 3D资产管理也称为3D内容管理。 随着游戏、电影、建筑、工程等行业中 3D 内容的增长&#xff0c;实施有效的资产管理工作流程对于提高生产力、减少错误、简化工作流程以及使…

Xinstall微信调起APP,提升用户体验与转化率

在移动互联网时代&#xff0c;APP已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;随着市场竞争的加剧&#xff0c;如何让用户更便捷地使用APP&#xff0c;提高分享营销的下载转化率&#xff0c;成为了开发者们亟待解决的问题。今天&#xff0c;我们将向大家介绍一款…

C/C++的内存管理与初阶模板

引言 我们在学习C的时候&#xff0c;会经常在堆上申请空间&#xff0c;所以这个时候就体现了内存管理遍历。 图下是我们常见的计算机的内存划分&#xff1a; 我也在图下对部分变量存在的位置&#xff0c;及时标注。(如果有任何问题可以联系博主修改&#xff0c;感谢大家。) 那…

如何在Windows上使用Docker,搭建一款实用的个人IT工具箱It- Tools

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

Docker安装主从数据库

首先开启docker后直接执行命令 docker run -d \ -p 3307:3306 \ -v /xk857/mysql/master/conf:/etc/mysql/conf.d \ -v /xk857/mysql/master/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name mysql-master \ mysql:8.0.29 默认情况下MySQL的binlog日志是自动开…

深入浅出Redis(八):Redis的集群模式

引言 Redis是一款优秀的键值对、内存非关系型数据库&#xff0c;单机节点下的Redis存在无法保证高可用、容量不足等问题 上篇文章介绍的哨兵主要能够保证主从架构下Redis的可用性&#xff0c;但是仍然存在容量不足、推举新的主节点时不能访问Redis的问题&#xff0c;集群可水…

#QT(串口助手-界面)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;编写串口助手 3.记录 接收框:Plain Text Edit 属性选择&#xff1a;Combo Box 发送框:Line Edit 广告&#xff1a;Group Box &#xff08;1&#xff09;仿照现有串口助手设计UI界面 &#xff08;2&#xff09;此时串口助手大…

ai脚本创作的软件有哪些?分享3款好用的工具!

随着人工智能技术的飞速发展&#xff0c;AI脚本创作软件已经成为内容创作者们的新宠。这些软件不仅能够帮助我们更高效地生成文章、视频脚本等&#xff0c;还能为我们提供独特的创意视角和无限的灵感。本文将带您深入了解几款备受瞩目的AI脚本创作软件&#xff0c;看看它们如何…