MySQL 联合索引

文章目录

  • 1.简介
  • 2.最左匹配
  • 3.最左匹配原理
  • 4.如何建立联合索引?
  • 5.覆盖索引
  • 参考文献

1.简介

联合索引指建立在多个列上的索引。

MySQL 可以创建联合索引(即多列上的索引)。一个索引最多可以包含 16 列。

联合索引可以测试包含索引中所有列的查询,或仅测试第一列、前两列、前三列等等的查询。如果在索引定义中以正确的顺序指定列,则复合索引可以加快对同一表的多种查询的速度。

下面是一个联合索引的例子。

CREATE TABLE test (id         INT NOT NULL,last_name  CHAR(30) NOT NULL,first_name CHAR(30) NOT NULL,PRIMARY KEY (id),INDEX name (last_name,first_name)
);

name 索引是针对 last_name 和 first_name 列的索引。该索引可加速查询。这些查询为 last_name 和 first_name 值的组合。或仅指定 last_name 值的查询,因为该列是索引的最左侧前缀,即联合索引支持最左匹配。

2.最左匹配

如果 SQL 语句用到了联合索引中最左边的字段,那么这条 SQL 语句就可以利用这个联合索引进行匹配,这便是最左匹配。

值得注意的是,当遇到范围查询 (>、<、between、like) 就会停止匹配

假设,我们对 (a,b) 字段建立一个索引,也就是说,如果 WHERE 条件为下面的则可以匹配索引。

a = 1
a = 1 AND b = 2
// 可以匹配索引,优化器会自动调整 a,b 的顺序与索引顺序一致。
b = 2 AND a = 1 

相反的,下面的条件将无法匹配索引了。

b = 2

而你对 (a,b,c,d) 建立索引,如果条件为:

a = 1 AND b = 2 AND c > 3 AND d = 4

那么 a,b,c 三个字段能用到索引,而 d 就匹配不到,因为遇到了范围查询。

3.最左匹配原理

最左匹配是针对联合索引来说的,所以我们可以从联合索引的原理来了解最左匹配。

我们都知道索引的底层是一颗 B+ 树,那么联合索引当然也是一颗 B+ 树,只不过联合索引的键值不是一个,而是多个。构建一颗 B+ 树只能根据一个键值来构建,因此数据库依据联合索引最左边的字段来构建 B+ 树。

假设我们对 (a,b) 字段建立索引:

在这里插入图片描述

如图所示是按照 a 来进行排序,在 a 相等的情况下,才按 b 来排序。

所以这就能够解释为什么条件 a=1 AND b=2 可以利用索引而 b=2 不能利用索引,因为 b 在全局是无序的,只有 a 确定的情况下,b 才是有序。

4.如何建立联合索引?

有了上面的基础,我们可以看一下关于联合索引常见的面试问题。

(1)如果 SQL 为:

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;

如果此题回答为对 (a,b,c) 建立索引,那就可以回去等通知了。

此题正确答案是任意顺序都可以, 如 (a,b,c) 或 (b,a,c) 或 (c,a,b) 都可以,重点是要将区分度高的字段放在前面,区分度低的字段放后面。像性别、状态这种字段区分度就很低,我们一般放后面。

例如假设区分度由大到小为 b,a,c。那么我们就对 (b,a,c) 建立索引。在执行 SQL 的时候,优化器会帮我们调整 WHERE 后 a,b,c 的顺序,让我们用上索引。

(2)如果 SQL 为:

SELECT * FROM table WHERE a > 1 AND b = 2;

如果此题回答为对 (a,b) 建立索引,那就可以回去等通知了。

正确答案对 (b,a) 建立索引。如果你建立的是 (a,b) 索引,那么只有 a 字段能用得上索引,毕竟最左匹配遇到范围查询就停止匹配。

如果对 (b,a) 建立索引那么两个字段都能用上,优化器会帮我们调整 WHERE 后 a,b 的顺序,让我们用上索引。

(3)如果 SQL 为:

SELECT * FROM table WHERE a > 1 and b = 2 and c > 3;  

此题回答是 (b,a) 或 (b,c) 都可以,要结合具体情况具体分析。

拓展一下:

SELECT * FROM table WHERE a = 1 AND b = 2 AND c > 3;

根据最左匹配,因为字段 c 是范围查询应该放到最后,所以应该建立 (a,b,c) 或 (b,a,c)。

(4)如果 SQL 为:

SELECT * FROM table WHERE a = 1 ORDER BY b;

对 (a,b) 建索引,当 a = 1 的时候,b 相对有序,可以避免再次排序。

拓展以下,如果 SQL 为:

SELECT * FROM table WHERE a > 1 ORDER BY b;

对 (a) 建立索引,因为 a 的值是一个范围,这个范围内 b 值是无序的,没有必要对 (a,b) 建立索引。

(5)如果 SQL 为:

SELECT * FROM table WHERE a IN (1,2,3) AND b > 1;

还是对 (a, b) 建立索引,因为 IN 在这里可以视为等值引用,不会中止索引匹配,所以还是 (a,b)。

5.覆盖索引

覆盖索引(Covering Index)指的是一个索引包含了所有需要查询的字段,而不必回到实际的数据行中查找。当一个查询可以直接从索引中获取所有需要的信息时,就称之为覆盖索引。

-- 创建表
CREATE TABLE mytable (col1 INT,col2 INT,col3 VARCHAR(255),INDEX idx_covering (col1, col2)
);-- 覆盖索引查询
-- 因为 idx_covering 包含了查询所需的所有列,所以是一个覆盖索引查询
SELECT col1, col2 FROM mytable WHERE col1 = 1 AND col2 = 2;

覆盖索引(Covering Index)是一种索引优化技术,旨在最小化查询开销。

联合索引有一个作用就是实现覆盖索引,如果联合索引包含了查询所需的所有列,那么查询可以直接从索引中获取所需的数据,避免了额外的表访问,这可以减少 I/O 操作,提高查询性能。

当然单列索引也可以实现覆盖索引,即查询的列是索引列。


参考文献

8.3.1 How MySQL Uses Indexes - MySQL
8.3.6 Multiple-Column Indexes - MySQL
面试官:谈谈你对mysql联合索引的认识?

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

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

相关文章

关于在Ubuntu20.04(ROS1 noetic)中使用catkin_make编译时发生的与pyhton版本不兼容的问题解决办法

今天在另外一台电脑上操作复现【ROS建模&#xff1a;一起从零手写URDF模型】这个博客时&#xff0c;发生了一些问题&#xff0c;特此记录下来 【ROS建模&#xff1a;一起从零手写URDF模型】链接&#xff1a;https://blog.csdn.net/qq_54900679/article/details/135726348?spm…

JasperReports渲染报表文件时候,读取图片报错:Byte data not found at:xxx.png.\r\n\tat

目录【知识星球】 1.1、错误描述 1.2、解决方案 1.1、错误描述 最近在工作中&#xff0c;使用JasperReports报表比较多一些&#xff0c;有次线上环境里面运行报错&#xff0c;查看报错日志&#xff0c;如下所示&#xff1a; net.sf.jasperreports.engine.JRException: Byte…

Spring Boot 启动错误【Kotlin】

目录 错误详情 错误原因 解决方法一 解决方法二 错误详情 Kotlin:     Module was compiled with an incompatible version of Kotlin.     The binary version of its metadata is 1.7.1, expected version is 1.1.16. 错误原因 编译器或构建工具的版本不匹配所造…

(免费领源码)python#Mysql苏州一日游之可视化分析69216-计算机毕业设计项目选题推荐

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对旅游服务等问题&#xff0c;对旅游服务进行…

docker 构建应用

docker 应用程序开发手册 开发 docker 镜像 Dockerfile 非常容易定义镜像内容由一系列指令和参数构成的脚本文件每一条指令构建一层一个 Dockerfile 文件包含了构建镜像的一套完整指令指令不区分大小写&#xff0c;但是一般建议都是大写从头到尾按顺序执行指令必须以 FROM 指…

Web3.0投票如何做到公平公正且不泄露个人隐私

在当前的数字时代&#xff0c;社交平台举办投票活动已成为了一种普遍现象。然而&#xff0c;随之而来的是一些隐私和安全方面的顾虑&#xff0c;特别是关于个人信息泄露和电话骚扰的问题。期望建立一个既公平公正又能保护个人隐私的投票系统。Web3.0的出现为实现这一目标提供了…

java web mvc-04-Apache Wicket

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails 开源 The jdbc pool for java.(java …

完美调试android-goldfish(linux kernel) aarch64的方法

环境要求 Mac m1Mac m1 中 虚拟机安装aarch64 ubuntu22.02Mac m1安装OrbStack&#xff0c;并在其中安装 ubuntu20.04&#xff08;x86_64&#xff09; 构建文件系统 在虚拟机 aarch64 ubuntu22.02中构建 安装必要的库 sudo apt-get install libncurses5-dev build-essenti…

【江科大】STM32:MPU6050介绍

文章目录 MPU6050介绍结构图MPU6050参数硬件电路模块内部结构框图数据帧格式寄存器地址 MPU6050介绍 MPU6050是一个6轴姿态传感器&#xff0c;可以测量芯片自身X、Y、Z轴的加速度、角速度参数&#xff0c;通过数据融合&#xff0c;可进一步得到姿态角&#xff0c;常应用于平衡…

STM32CubeMX教程27 SDIO - 读写SD卡

目录 1、准备材料 2、实验目标 3、轮询方式读取SD卡流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.0、工程基本配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.0、配置Project Manager页面 3.2.1、外设初始化调用流程 3.2.2、外设中断调用流…

现货黄金做日内交易和波段交易有何差异?

在现货黄金投资中&#xff0c;日内交易和波段交易都是投资者常用的手段。但投资者其实搞不懂两者有何区别&#xff0c;有时甚至不清楚自己做的是日内交易还是波段交易&#xff0c;下面我们就来讨论一下这两种交易方法的异同。 两者的区别主要是在持仓的时间上。日内交易顾名思义…

Python中的`__all__`魔法函数使用详解

概要 Python是一门灵活而强大的编程语言&#xff0c;提供了各种机制来控制模块的导入和访问。其中&#xff0c;__all__魔法函数是一种用于限制模块导入的机制&#xff0c;可以明确指定哪些变量、函数或类可以被导入。本文将深入探讨__all__的作用、用法以及示例&#xff0c;以…

C++:类和对象(中)

类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成…

ES文档索引、查询、分片、文档评分和分析器技术原理

技术原理 索引文档 索引文档分为单个文档和多个文档。 单个文档 新建单个文档所需要的步骤顺序&#xff1a; 客户端向 Node 1 发送新建、索引或者删除请求。节点使用文档的 _id 确定文档属于分片 0 。请求会被转发到 Node 3&#xff0c;因为分片 0 的主分片目前被分配在 …

【AI绘画】stablediffusion图生图教程!!

**手把手教你入门绘图超强的AI绘画&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包 &#xff08;文末可获取&#xff09; ** 目录 一、图生图 1.图生图原理 2.图生图三个步骤 ①图生图基本三步法 ②提示…

Leetcode—2859. 计算 K 置位下标对应元素的和【简单】

2023每日刷题&#xff08;九十一&#xff09; Leetcode—2859. 计算 K 置位下标对应元素的和 内置函数__builtin_popcount方法实现代码 class Solution { public:int sumIndicesWithKSetBits(vector<int>& nums, int k) {int n nums.size();int ans 0;for(int i …

mac电脑安卓文件传输工具:Android File Transfer直装版

Android File Transfer&#xff08;AFT&#xff09;是一款用于在Mac操作系统上与Android设备之间传输文件。它允许用户将照片、音乐、视频和其他文件从他们的Android手机或平板电脑传输到Mac电脑&#xff0c;以及将文件从Mac上传到Android设备。 下载地址&#xff1a;https://w…

怎样编写高性能C/C++程序

本文主要讨论高性能编程&#xff0c;而且是那种“极致性能需求”。按照本人的粗浅认识&#xff0c;应该已经覆盖了绝大多数技术要点&#xff0c;但缺点是不够详细&#xff08;篇幅有限&#xff09;。本文共分为4个部分&#xff1a;总体论述、高性能网络编程、高性能数值计算、常…

【揭秘】ForkJoinTask全面解析

内容摘要 ForkJoinTask的显著优点在于其高效的并行处理能力&#xff0c;它能够将复杂任务拆分成多个子任务&#xff0c;并利用多核处理器同时执行&#xff0c;从而显著提升计算性能&#xff0c;此外&#xff0c;ForkJoinTask还提供了简洁的API和强大的任务管理机制&#xff0c…

常规的管理系统除了适用该有的范儿一定要有!气质上不能输

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 常规的管理系统除了适用该有的范儿一定要有!气质上不能输 在现今快速发展的商业环境中…