首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL 联合索引

MySQL 联合索引

作者头像
恋喵大鲤鱼
发布于 2024-01-27 04:43:45
发布于 2024-01-27 04:43:45
44100
代码可运行
举报
文章被收录于专栏:C/C++基础C/C++基础
运行总次数:0
代码可运行

1.简介

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 条件为下面的则可以匹配索引。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a = 1
a = 1 AND b = 2
// 可以匹配索引,优化器会自动调整 a,b 的顺序与索引顺序一致。
b = 2 AND a = 1 

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
b = 2

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a > 1 AND b = 2;

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

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

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

(3)如果 SQL 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a > 1 and b = 2 and c > 3;  

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

拓展一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a = 1 AND b = 2 AND c > 3;

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

(4)如果 SQL 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a = 1 ORDER BY b;

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

拓展以下,如果 SQL 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a > 1 ORDER BY b;

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

(5)如果 SQL 为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM table WHERE a IN (1,2,3) AND b > 1;

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

5.覆盖索引

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 创建表
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联合索引的认识?

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【图文详解:索引极简教程】SQL 查询性能优化原理
在一本厚厚的书籍的前几页,通常会有几页目录。作用是让读者可以快速找到感兴趣的章节进行阅读。 目录之所以可以快速阅读,是因为它提前进行了结构化+有序处理。
一个会写诗的程序员
2022/03/07
8820
【图文详解:索引极简教程】SQL 查询性能优化原理
面试官出的 MySQL 索引的问题,这篇文章全给你解决!
这篇文章会讲解索引的基础知识,但主要是关于MySQL数据库的B+树索引的相关原理,里面的一些知识都参考了MySQL技术内幕这本书,也算对于这些知识的总结。对于B树和B+树相关的知识,可以参考我的这篇博客:面试官问你B树和B+树,就把这篇文章丢给他
好好学java
2019/10/09
5170
面试官出的 MySQL 索引的问题,这篇文章全给你解决!
mysql建立联合索引_mysql之联合索引
create index `sindex` on `test` (`aaa`,`bbb`,`ccc`);
全栈程序员站长
2022/09/06
5.6K0
1 W 字+ | 硬刚 MySQL(典藏版)
先说下哈,这次给大家带来的大厂面试题,都来源于我的知识星球,总共 20 道题,17 道题来自悟空分享,另外 3 道题来自 MySQL 大牛:东哥。
悟空聊架构
2022/05/13
4950
1 W 字+ | 硬刚 MySQL(典藏版)
九个实验:MySQL 联合索引的最左匹配原则
最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。
悟空聊架构
2023/10/02
2.1K0
你确定真正理解联合索引和最左前缀原则?
前文已经说了explain命令的大部分参数,接着图解: EXPLAIN 实战-1这篇文章把explain的key_len参数分享完,接着分享最左前缀原则,建立如下的表,其中name列和address列都建立了索引
Java识堂
2019/08/13
8500
什么是最左前缀匹配?为什么要遵守?
在 MySQL 中,最左前缀匹配指的是在查询时利用索引的最左边部分进行匹配。当你执行查询时,如果查询条件涉及到组合索引的前几个列,MySQL 就能够利用该复合索引来进行匹配。
@派大星
2024/05/29
9200
什么是最左前缀匹配?为什么要遵守?
【知识】MySQL索引原理及慢查询优化
MySQL用来加快查询的技术很多,其中最重要的是索引。通常索引能够快速提高查询速度。如果不适用索引,MYSQL必须从第一条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。但也不全是这样。本文讨论索引是什么以及如何使用索引来改善性能,以及索引可能降低性能的情况。
辉哥
2021/06/10
1.2K0
【知识】MySQL索引原理及慢查询优化
MySQL索引原理
MySQL索引原理 MySQL 的索引 概述 索引是数据库中一个排序的数据结构,用来协助快速查询和更新数据库表中的数据;数据是以文件的形式存放在磁盘上的,每一行数据都有它的磁盘地址;当没有索引时,比如从 **500w** 条数据中检索出一条数据,只能依次遍历这张表的全部数据,直到找到这条数据。但是有了索引后,只需要在索引里去检索这条数据就可以了,因为它是一种专门进行数据检索特殊的数据结构,在找到数据存放的磁盘地址后就可以拿到数据。在 **InnoDB** 存储引擎中,索引有三类: 普通(**norm
编程之心
2021/07/14
4930
MySQL索引原理
一文读懂MySQL的索引结构及查询优化
(同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本)
Python之道
2021/01/06
9460
mysql联合索引详解
上一篇文章:mysql数据库索引优化 比较简单的是单列索引(b+tree)。遇到多条件查询时,不可避免会使用到多列索引。联合索引又叫复合索引。 b+tree结构如下: 每一个磁盘块在mysql中是一个页,页大小是固定的,mysql innodb的默认的页大小是16k,每个索引会分配在页上的数量是由字段的大小决定。当字段值的长度越长,每一页上的数量就会越少,因此在一定数据量的情况下,索引的深度会越深,影响索引的查找效率。 对于复合索引(多列b+tree,使用多列值组合而成的b+tree索引)。遵循最左侧原
企鹅号小编
2018/01/29
9.5K2
【干货】MySQL索引与优化实践
索引的目的在于提高查询效率,其功能可类比字典,通过该索引可以查询到我们想要查询的信息,因此,选择建立好的索引十分重要
搜云库技术团队
2019/10/17
9170
MySQL 联合索引底层存储结构及索引查找过程解读
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/20
3.3K0
MySQL 联合索引底层存储结构及索引查找过程解读
【MySQL】索引啊 d=====( ̄▽ ̄*)b
A database index is a data structure that improves the speed of operations in a table. Indexes can be created using one or more columns, providing the basis for both rapid random lookups and efficient ordering of access to records.
JuneBao
2022/10/26
1.1K0
【MySQL】索引啊 d=====( ̄▽ ̄*)b
MySQL数据库:SQL优化与索引优化
假如有联合索引 (emp_no 、title、from_date ),那么下面的 SQL 中 emp_no 可以用到索引,而title 和 from_date 则使用不到索引。
全栈程序员站长
2022/06/29
1.6K0
关于数据库索引的一些常识
索引覆盖(Covering Index)或称为覆盖索引,是数据库中的一种优化手段。
bisal
2025/07/04
960
关于数据库索引的一些常识
MySQL索引优化实战
众所周知,索引类似于字典的目录,可以提高查询的效率。 索引从物理上可以分为:聚集索引,非聚集索引 从逻辑上可以分为:普通索引,唯一索引,主键索引,联合索引,全文索引
Java识堂
2019/05/21
1.2K0
MySQL 索引知识点总结
作者:fanili,腾讯 WXG 后台开发工程师 知其然知其所以然!本文介绍索引的数据结构、查找算法、常见的索引概念和索引失效场景。 什么是索引? 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。(百度百科) 索引的目的是提高查找效率,对数据表的值集合进行了排序,并按照一定数据结构进行了存储。 本文将从一个案
腾讯技术工程官方号
2020/12/16
1.1K0
深入剖析 MySQL 索引和 SQL 调优实战(珍藏版)
MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。
lyb-geek
2019/11/08
7560
相关推荐
【图文详解:索引极简教程】SQL 查询性能优化原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档