mysql联合索引和最左匹配问题。

news2024/11/25 18:40:41

1引言:

如果频繁地使⽤相同的⼏个字段查询,就可以考虑建⽴这⼏个字段的联合索引来提⾼查询效率。⽐如对 于联合索引 test_col1_col2_col3,实际建⽴了 (col1)、(col1, col2)、(col, col2, col3) 三个索引。联合 索引的主要优势是减少结果集数量:如果根据 col1、col2、col3 的单列索引进⾏查询,需要分别得到 num[i] 个结果,然后再取交集;⽽如果使⽤联合索引查询,只会得到很少的⼀段数据。 最左匹配原则:这些索引能够被包含 col1、(col1 col2)、(col1 col2 col3) 的查询利⽤到,但是不能够 被 col2、(col2、col3) 的等值查询利⽤到。这与底层实现有关。联合索引的最左匹配原则,在遇到范围 查询(>、<、between、like 包括like '林%'这种)的时候,就会停⽌匹配,也就是范围列可以⽤到联合 索引,但是范围列后⾯的列⽆法⽤到联合索引。但是如果是 >=、<= 时可以继续⾛索引。

2.实例化过程

        
        当使用MySQL创建数据库表时,可以使用以下语法:
        
CREATE TABLE table_name (
    column1 datatype constraint,
    column2 datatype constraint,
    ...
    PRIMARY KEY (column1),
    INDEX index_name (column2, column3)
);

其中,table_name 是要创建的表的名称,column1column2, ... 是表的列名,datatype 是列的数据类型,constraint 是列的约束条件。

要创建联合索引,可以使用 INDEX 关键字,后面跟着索引的名称和要包含在索引中的列名。在创建联合索引时,列名之间使用逗号分隔。

最左匹配原则是指在联合索引中,索引会按照列的顺序进行排序,并且查询时只能使用索引的最左边的列开始匹配。这意味着如果查询中的条件不包含索引的最左边的列,那么索引将无法被使用。

例如,假设有一个名为 users 的表,包含以下列:idfirst_namelast_nameemail。我们想要创建一个联合索引,包含 first_name 和 last_name 列:

CREATE TABLE users (
    id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100),
    INDEX name_index (first_name, last_name)
);

让我们在上面创建的 users 表中插入一些数据来验证最左匹配原则。

INSERT INTO users (id, first_name, last_name, email) VALUES
(1, 'John', 'Doe', 'john.doe@example.com'),
(2, 'Jane', 'Smith', 'jane.smith@example.com'),
(3, 'John', 'Smith', 'john.smith@example.com'),
(4, 'Jane', 'Doe', 'jane.doe@example.com');

上述语句将向 users 表中插入四条数据。现在,我们可以使用不同的查询条件来验证最左匹配原则。

查询条件包含索引的最左边的列:

SELECT * FROM users WHERE first_name = 'John' AND last_name = 'Doe';

这个查询将返回 id=1 的记录,因为查询条件完全匹配了索引的最左边的列。

SELECT * FROM users WHERE first_name = 'John' AND last_name = 'Smith';

这个查询将返回  id=3 的记录,因为查询条件完全匹配了索引的最左边的列和第二个列。
SELECT * FROM users WHERE last_name = 'Doe';

这个查询将无法使用索引,因为查询条件没有包含索引的最左边的列。它将执行全表扫描,返回所有满足 last_name = 'Doe' 的记录。

通过以上示例,我们可以看到最左匹配原则的效果。只有当查询条件包含索引的最左边的列时,索引才能被充分利用,加速查询。否则,索引将无法被使用,查询将变得较慢。

3.说明

左匹配原则就是指在联合索引中,如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配。例如某表现有索引(a,b,c),现在你有如下语句:
        
select * from t where a=1 and b=1 and c =1;     #这样可以利用到定义的索引(a,b,c),用上a,b,c

select * from t where a=1 and b=1;     #这样可以利用到定义的索引(a,b,c),用上a,b

select * from t where b=1 and a=1;     #这样可以利用到定义的索引(a,b,c),用上a,c(mysql有查询优化器)

select * from t where a=1;     #这样也可以利用到定义的索引(a,b,c),用上a

select * from t where b=1 and c=1;     #这样不可以利用到定义的索引(a,b,c)

select * from t where a=1 and c=1;     #这样可以利用到定义的索引(a,b,c),但只用上a索引,b,c索引用不到
也就是说通过最左匹配原则你可以定义一个联合索引,但是使得多中查询条件都可以用到该索引。
值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。也就是:
        
select * from t where a=1 and b>1 and c =1; #这样a,b可以用到(a,b,c),c索引用不到 

这条语句只有 a,b 会用到索引,c 都不能用到索引。这个原因可以从联合索引的结构来解释。

但是如果是建立(a,c,b)联合索引,则a,b,c都可以使用索引,因为优化器会自动改写为最优查询语句。

select * from t where a=1 and b >1 and c=1;  #如果是建立(a,c,b)联合索引,则a,b,c都可以使用索引
#优化器改写为
select * from t where a=1 and c=1 and b >1;

这也是最左前缀原理的一部分,索引index1:(a,b,c),只会走a、a,b、a,b,c 三种类型的查询,其实这里说的有一点问题,a,c也走,但是只走a字段索引,不会走c字段。

另外还有一个特殊情况说明下,select * from table where a = '1' and b > ‘2’ and c='3' 这种类型的也只会有 a与b 走索引,c不会走。

像select * from table where a = '1' and b > ‘2’ and c='3' 这种类型的sql语句,在a、b走完索引后,c肯定是无序了,所以c就没法走索引,数据库会觉得还不如全表扫描c字段来的快。

以index (a,b,c)为例建立这样的索引相当于建立了索引a、ab、abc三个索引。一个索引顶三个索引当然是好事,毕竟每多一个索引,都会增加写操作的开销和磁盘空间的开销。

 

参考: https://www.cnblogs.com/-mrl/p/13230006.html

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

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

相关文章

深入理解Python中的布尔值:真与假

Python作为一门强大的编程语言&#xff0c;具有丰富的数据类型和逻辑运算&#xff0c;其中布尔&#xff08;Boolean&#xff09;值在控制程序流程和逻辑决策中扮演着关键的角色。本文将深入探讨Python中的布尔值&#xff0c;解释什么是真&#xff08;True&#xff09;和假&…

pytorch加载的cifar10数据集,到底有没有经过归一化

pytorch加载cifar10的归一化 pytorch怎么加载cifar10数据集torchvision.datasets.CIFAR10transforms.Normalize()进行归一化到底在哪里起作用&#xff1f;【CIFAR10源码分析】 torchvision.datasets加载的数据集搭配Dataloader使用model.train()和model.eval() pytorch怎么加载…

Paste v4.1.2(Mac剪切板)

Paste for Mac是一款运行在Mac OS平台上的剪切板小工具&#xff0c;拥有华丽的界面效果&#xff0c;剪切板每一条记录可显示&#xff08;预览&#xff09;文本&#xff0c;图片等记录的完整内容&#xff0c;可以记录最近指定条数的剪切板信息&#xff0c;方便用户随时调用&…

输电线路AR可视化巡检降低作业风险

随着现代工业的快速发展&#xff0c;各行业的一线技术工人要处理的问题越来越复杂&#xff0c;一些工作中棘手的问题迫切需要远端专家的协同处理。但远端专家赶来现场往往面临着专家差旅成本高、设备停机损失大、专业支持滞后、突发故障无法立即解决等痛点。传统的远程协助似乎…

Emacs之高亮显示超过80个字符部分(一百三十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Linux入门知识

​ 文章目录 一、Linux发展历程1.1、Linux前身-Unix1.2、Linux 诞生 二、Linux系统特点三、Linux 分支四、Linux系统架构4.1、系统调用4.2、Linux shell4.3、Linux文件系统4.4、Linux内核 团队博客: 汽车电子社区 一、Linux发展历程 1.1、Linux前身-Unix 1968年Multics 项目…

【Excel】如何画不同时序交叉的百分比堆积柱状图

这里写自定义目录标题 1 将两表交叉合并为一个表1.1 步骤一&#xff1a;在两独立表的工作天数和工资列下面按1-n顺次标号。1.2 步骤二&#xff1a;选中两表需要合并的部分&#xff0c;调出自定义排序1.3 步骤三&#xff1a;选项 ——> 按行排序 &#xff08;选完后点确定&am…

LV.12 D17 中断控制器 学习笔记

一、中断控制器 在处理IRQ的时候&#xff0c;会将CPSR写入IRQ_SPSR&#xff0c;然后将CPU切换为IRQ模式&#xff0c;把状态改成ARM状态&#xff0c;把I位写成1禁止全部的IRQ&#xff0c;所以中断这样是我们不想要的。4412是一个四核的CPU&#xff0c;在发送中断前要确定发送给哪…

【UDS基础】简单介绍“统一诊断服务“

1. 前言 我们将在这个实用教程中介绍UDS的基础知识,重点关注在CAN总线上的UDS(UDSonCAN)和CAN诊断(DoCAN)。此外,我们还会介绍ISO-TP协议,并解释UDS、OBD2、WWH-OBD和OBDonUDS之间的差异。 最后,我们将解释如何请求、记录和解码UDS消息,并提供一些实际示例,例如记录…

libevent

libevent 库概念和特点 开源。精简。跨平台&#xff08;Windows、Linux、maxos、unix&#xff09;。专注于网络通信&#xff08;不一定非用在网络当中&#xff0c;比如下面的读写管道&#xff09;。 libevent特性&#xff1a;基于"事件"&#xff0c;面向“文件描述符…

C++算法:第N位数的原理、源码及测试用例

本文涉及知识点 简单的数学知识。 本博文对应源码&#xff0c;审核比较慢&#xff0c;请耐心等待&#xff1a;https://download.csdn.net/download/he_zhidan/88504919 本博文在CSDN 学院有对应课程。 题目 给你一个整数 n &#xff0c;请你在无限的整数序列 [1, 2, 3, 4, 5…

编译原理(1)----LL(1)文法(首符号集,后跟符号集,选择符号集)

一.首符号集&#xff08;First()&#xff09; 技巧&#xff1a;找最左边可能出现的终结符 例&#xff1a; 1.First(E) E->T,最左边为T&#xff0c;又因为T->F,最左边为F&#xff0c;F->(E)|i,则最左边为{&#xff08;&#xff0c;i } 2.First(T):只需要看符号串最左…

Mac VsCode g++编译报错:不支持C++11语法解决

编译运行时报错&#xff1a; [Running] cd “/Users/yiran/Documents/vs_projects/c/” && g 1116.cpp -o 1116 && "/Users/yiran/Documents/vs_projects/c/"1116 1116.cpp:28:22: warning: range-based for loop is a C11 extension [-Wc11-extensi…

pda条码二维码扫描数据采集安卓手持终端扫码热敏标签打印一体机

HT800新一代移动物联终端是深圳联强优创信息科技有限公司自主研发的基于Android11操作系统的高性能、高可靠的工业级手持数据终端&#xff0c;能与其它设备进行无线通讯&#xff0c;提供良好的操作界面&#xff0c;支持条码扫描、RFID读写&#xff08;NFC&#xff09;、GPS定位…

ch579串口编程笔记

“CH579SFR.h”库文件&#xff0c;关于串口中断部分 /* UART interrupt identification values for IIR bits 3:0 */ #define UART_II_SLV_ADDR 0x0E // RO, UART0 slave address match #define UART_II_LINE_STAT 0x06 // R…

云服务器哪家便宜靠谱 | 简单了解亚马逊云科技发展史

云服务器哪家便宜又靠谱呢&#xff1f;为什么说亚马逊云科技在这道题答案的第一行&#xff0c;一篇故事告诉你。 1994年&#xff0c;杰夫贝索斯在西雅图创建了亚马逊&#xff0c;最初只是一个在线书店。 1997年&#xff0c;亚马逊在纳斯达克交易所上市&#xff0c;成为一家公…

基于 Odoo + Python 的网站快速开发指南

基于 Odoo Python 的网站快速开发指南 下载根据本指南开发的主题模块源码 Odoo 网站生成器是一个灵活的工具&#xff0c;可以轻松构建与 Odoo 应用完全集成的网站。使用其提供的主题选项 (options) 和构建块 (blocks) 很容易定制网站。然而&#xff0c;你还可以更进一步深度定…

JavaEE进阶3

传递数组: 当我们请求中,同一个参数有多个时,浏览器就会帮我们封装成一个数组 用逗号进行分割也是可以的(有的浏览器不能直接使用逗号,需要我们去转码) 传递集合: HTTP 状态码(不是后端自定义的) 2XX:成功 3XX:重定向 4XX:客户端错误 5XX:服务器错误 业务状态码:HTTP响应…

第十章 Python 自定义模块及导入方法

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

Cookie、Session、Token、JWT 一篇就够了

什么是认证&#xff08;Authentication&#xff09; 通俗地讲就是验证当前用户的身份&#xff0c;证明“你是你自己”&#xff08;比如&#xff1a;你每天上下班打卡&#xff0c;都需要通过指纹打卡&#xff0c;当你的指纹和系统里录入的指纹相匹配时&#xff0c;就打卡成功&a…