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.hqwc.cn/news/434335.html

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

相关文章

构建一个安全可靠的身份认证中心和资源服务中心:SpringSecurity+OAuth2.0的完美结合

目录 1、引言 1.1 身份认证和授权的重要性 1.2 SpringSecurity和OAuth2.0的概述 2、架构设计 2.1 组件概述 2.2 身份认证中心的设计 2.3 资源服务中心的设计 3、身份认证中心的实现 3.1 用户管理 3.2 登录认证流程 3.3 令牌生成和管理 4、资源服务中心的实现 4.1 …

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…

大数据期望最大化(EM)算法:从理论到实战全解析

文章目录 大数据期望最大化&#xff08;EM&#xff09;算法&#xff1a;从理论到实战全解析一、引言概率模型与隐变量极大似然估计&#xff08;MLE&#xff09;Jensen不等式 二、基础数学原理条件概率与联合概率似然函数Kullback-Leibler散度贝叶斯推断 三、EM算法的核心思想期…

【Web】CTFSHOW SQL注入刷题记录(上)

目录 无过滤注入 web171 web172 web173 web174 web175 时间盲注 写马 过滤注入 web176 web177 web178 web179 web180 web181-182 web183 web184 web185-186 web187 web188 web189 web190 布尔盲注 web191 web192 web193 web194 堆叠注入 web195 …

算法训练营Day60(单调栈)

84.柱状图的最大矩形 84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 注意首尾加0的细节就可 class Solution {public int largestRectangleArea(int[] heights) {Deque<Integer> stack new LinkedList<>();int[] newHeight new int[heights.…

CSAPP fall2015 深入理解计算机系统 Cache lab详解

Cache Lab cache lab 缓存实验 代码下载 从CSAPP上面下载对应的lab代码 http://csapp.cs.cmu.edu/3e/labs.html 环境准备 需要安装 valgrind。可以参考文章Valgrind centos。 安装好以后执行valgrind --version可以看到版本号。 Cache simulator cache simulator not a …

软考复习之UML设计篇

UML统一建模语言 构件图&#xff1a;描述系统的物理结构&#xff0c;它可以用来显示程序代码如何分解成模块 部署图&#xff1a;描述系统中硬件和软件的物理结构&#xff0c;它描述构成系统架构的软件构件&#xff0c;处理器和设备 用例图&#xff1a;描述系统与外部系统及用…

matlab对负数开立方根得到虚数的解决方案

问题描述&#xff1a;在matlab中&#xff0c;对负数开立方根&#xff0c;不出意外你将得到虚数。 例如 − 27 3 \sqrt[3]{-27} 3−27 ​&#xff0c;我们知道其实数解是-3&#xff0c;但在matlab中的计算结果如下&#xff1a; 问题原因&#xff1a;matlab中的立方根运算是在…

AI嵌入式K210项目-目录

系列文章简介 本系列文章简单介绍K210芯片的使用方法&#xff0c;大致分为两个部分 : C语言裸机开发MicroPython开发 学习第一部分有助于大家对K210芯片的外设接口和内置的各种硬件加速器有更深刻的了解&#xff0c;第二部分有助于大家快速实现功能&#xff1b; 实验所使用的…

Linux系统优化要义

这里不敢说 linux优化奥义&#xff0c;主要是本文比较浅显&#xff0c;适合普通开发相关人员去读 linux作为服务器系统的王者&#xff0c;以稳定性著称&#xff0c;但对于不同的“应用场景”&#xff0c;相关配置还需调整&#xff0c;才能保证业务稳定性。以下是相关总结 IO优…

野火霸道V2学习笔记

野火霸道V2学习笔记 STM32F103学习笔记说明基础配置配置KeilMDK配置串口下载程序美化Keil界面配置VScode 理论知识STM32命名方式例子 置位与清零GPIOGPIO简介GPIO和引脚的区别引脚的分类 GPIO 框图讲解保护二极管推挽输出开漏输出补充: 高阻态与悬空复用功能输出输入模式GPIO框…

SpringBoot之时间数据前端显示格式化

背景 在实际我们通常需要在前端显示对数据操作的时间或者最近的更新时间&#xff0c;如果我们只是简单的使用 LocalDateTime.now()来传入数据不进行任何处理那么我们就会得到非常难看的数据 解决方式&#xff1a; 1). 方式一 在属性上加上注解&#xff0c;对日期进行格式…