MySQL联合索引最左匹配原则
MySQL中的联合索引(也叫组合索引)遵循最左匹配原则,即在创建联合索引时,查询条件必须从索引的最左边开始,否则索引不会被使用。在联合索引的情况下,数据是按照索引第一列排序,第一列数据相同时才会按照第二列排序。
例如,假设有一个表t_employees,它有一个联合索引(first_name, last_name)。
(root@192.168.80.85)[superdb]> create table t_employees as select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY from employees;
Query OK, 91 rows affected (0.06 sec)
Records: 91 Duplicates: 0 Warnings: 0(root@192.168.80.85)[superdb]> select * from t_employees;
+-------------+-------------+-------------+----------+
| EMPLOYEE_ID | FIRST_NAME | LAST_NAME | SALARY |
+-------------+-------------+-------------+----------+
| 116 | Shelli | Baida | 2900.00 |
| 117 | Sigal | Tobias | 2800.00 |
| 118 | Guy | Himuro | 2600.00 |
| 119 | Karen | Colmenares | 2500.00 |
| 120 | Matthew | Weiss | 8000.00 |
| 121 | Adam | Fripp | 8200.00 |
| 122 | Payam | Kaufling | 7900.00 |
| 123 | Shanta | Vollman | 6500.00 |
| 124 | Kevin | Mourgos | 5800.00 |
| 125 | Julia | Nayer | 3200.00 |
| 126 | Irene | Mikkilineni | 2700.00 |
| 127 | James | Landry | 2400.00 |
| 128 | Steven | Markle | 2200.00 |
| 129 | Laura | Bissot | 3300.00 |
| 130 | Mozhe | Atkinson | 2800.00 |
| 131 | James | Marlow | 2500.00 |
| 132 | TJ | Olson | 2100.00 |
| 133 | Jason | Mallin | 3300.00 |
| 134 | Michael | Rogers | 2900.00 |
| 135 | Ki | Gee | 2400.00 |
| 136 | Hazel | Philtanker | 2200.00 |
| 137 | Renske | Ladwig | 3600.00 |
| 138 | Stephen | Stiles | 3200.00 |
| 139 | John | Seo | 2700.00 |
| 140 | Joshua | Patel | 2500.00 |
| 141 | Trenna | Rajs | 3500.00 |
| 142 | Curtis | Davies | 3100.00 |
| 143 | Randall | Matos | 2600.00 |
| 144 | Peter | Vargas | 2500.00 |(root@192.168.80.85)[superdb]> alter table t_employees add constraint pk_t_employees_id primary key(EMPLOYEE_ID);
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0(root@192.168.80.85)[superdb]> create index indx_t_employees_nameinfo on t_employees(FIRST_NAME,LAST_NAME);
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0(root@192.168.80.85)[superdb]> show index from t_employees;
+-------------+------------+---------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------------+------------+---------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| t_employees | 0 | PRIMARY | 1 | EMPLOYEE_ID | A | 91 | NULL | NULL | | BTREE | | | YES | NULL |
| t_employees | 1 | indx_t_employees_nameinfo | 1 | FIRST_NAME | A | 79 | NULL | NULL | YES | BTREE | | | YES | NULL |
| t_employees | 1 | indx_t_employees_nameinfo | 2 | LAST_NAME | A | 91 | NULL | NULL | | BTREE | | | YES | NULL |
+-------------+------------+---------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
3 rows in set (0.01 sec)
1、满足联合索引最左匹配原则
以下查询会使用这个联合索引:
SELECT * FROM t_employees WHERE first_name = ‘James’;
SELECT * FROM t_employees WHERE first_name = ‘James’ AND last_name = ‘Marlow’;
(root@192.168.80.85)[superdb]> explain SELECT * FROM t_employees WHERE first_name = 'James';
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | t_employees | NULL | ref | indx_t_employees_nameinfo | indx_t_employees_nameinfo | 83 | const | 2 | 100.00 | NULL |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)(root@192.168.80.85)[superdb]> explain SELECT * FROM t_employees WHERE first_name = 'James' and LAST_NAME='Marlow';
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | t_employees | NULL | ref | indx_t_employees_nameinfo | indx_t_employees_nameinfo | 185 | const,const | 1 | 100.00 | NULL |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
但是,下面的查询不会使用联合索引:
SELECT * FROM t_employees WHERE LAST_NAME=‘Marlow’;
(root@192.168.80.85)[superdb]> explain SELECT * FROM t_employees WHERE LAST_NAME='Marlow';
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | t_employees | NULL | ALL | NULL | NULL | NULL | NULL | 91 | 10.00 | Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
因为它们没有从索引的最左边开始。在联合索引的情况下,数据是按照索引第一列排序,第一列数据相同时才会按照第二列排序。
下面的查询会使用联合索引
(root@192.168.80.85)[superdb]> explain SELECT * FROM t_employees WHERE LAST_NAME='Marlow' and first_name = 'James';
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | t_employees | NULL | ref | indx_t_employees_nameinfo | indx_t_employees_nameinfo | 185 | const,const | 1 | 100.00 | NULL |
+----+-------------+-------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配。需要注意的是,因为有查询优化器,所以 first_name,last_name 字段在 where 子句的顺序并不重要
2、联合索引不遵循最左匹配原则,也是走全扫描二级索引树
我们都知道联合索引要遵循最左匹配才能走索引,但是如果数据库表中的字段都是索引的话,即使查询过程中,没有遵循最左匹配原则,也是走全扫描二级索引树(type=index)
如下的表结构及查询
(root@192.168.80.85)[superdb]> create table t_emplist as select EMPLOYEE_ID,FIRST_NAME,LAST_NAME from employees;
Query OK, 91 rows affected (0.10 sec)
Records: 91 Duplicates: 0 Warnings: 0(root@192.168.80.85)[superdb]> alter table t_emplist add constraint pk_t_emplist_id primary key(EMPLOYEE_ID);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0(root@192.168.80.85)[superdb]> create index indx_t_emplist_nameinfo on t_emplist(FIRST_NAME,LAST_NAME);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
如下面的查询会使用联合索引,但不是最左匹配原则
SELECT * FROM t_emplist WHERE LAST_NAME=‘Marlow’;
(root@192.168.80.85)[superdb]> explain SELECT * FROM t_emplist WHERE LAST_NAME='Marlow';
+----+-------------+-----------+------------+-------+-------------------------+-------------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+-------------------------+-------------------------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | t_emplist | NULL | index | indx_t_emplist_nameinfo | indx_t_emplist_nameinfo | 185 | NULL | 91 | 10.00 | Using where; Using index |
+----+-------------+-----------+------------+-------+-------------------------+-------------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.01 sec)
如果数据库表中的字段只有主键+二级索引,那么即使查询的where条件不满足最左匹配原则,也不会走全表扫描(type=all),而是走全扫描二级索引树(type=index)。
关键还是看数据表中的字段及索引情况。
相关文章:

MySQL联合索引最左匹配原则
MySQL中的联合索引(也叫组合索引)遵循最左匹配原则,即在创建联合索引时,查询条件必须从索引的最左边开始,否则索引不会被使用。在联合索引的情况下,数据是按照索引第一列排序,第一列数据相同时才会按照第二列排序。 例…...

2024最新最全面的软件测试自动化面试题(含答案)
1.如何把自动化测试在公司中实施并推广起来的? 选择长期的有稳定模块的项目 项目组调研选择自动化工具并开会演示demo案例,我们主要是演示selenium和robot framework两种。 搭建自动化测试框架,在项目中逐步开展自动化。 把该项目的自动化…...

Linux磁盘-MBRGPT
作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux磁盘涉及到的命令不是很多,但是在实际运维中的作用却很大,因为Linux系统及业务都会承载到硬盘上…...

kind kubernetes(k8s虚拟环境)使用本地docker的镜像
kubernetes中,虽然下载镜像使用docker,但是存储在docker image里的镜像是不能被k8s直接使用的,但是kind不同,可以使用下面的方法,让kind kubernetes环境使用docker image里的镜像。 kind – Quick Start 例如&#x…...

kafka发送消息流程
配置props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, RoundRobinPartitioner.class); public Map<String,Object> producerConfigs(){Map<String,Object> props new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapServers…...

使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-敌人生成器(八)
文章目录 开发思路敌人生成器代码分析属性配置 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击(一) 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-激光组件(二) 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-飞…...

Allegro中show elements不弹窗问题
今天allegro用的好好的,刚刚还可以正常使用show elements进行对象的详细信息查看的,突然就不好使了,具体表现为不弹窗。 找了好久找到一个类似问题的,具体的解决方法是: D:\Allegro\Cadence\SPB_Data\pcbenv在allegro的…...

【C++】继承最全解析(什么是继承?继承有什么用?)
目录 一、前言 二、什么是继承 ? 💢继承的概念💢 💢继承的定义💢 🥝定义格式 🍇继承权限 三、基类与派生类对象的赋值转换 四、继承的作用域 五、派生类中的默认成员函数 💢…...

STM32-外部中断浅析
本篇解释了STM32中断原理 MCU为什么需要中断 中断,是嵌入式系统中很重要的一个功能,在系统运行过程中,当出现需要立刻处理的情况时,暂停当前任务,转而处理紧急任务,处理完毕后,恢复之前的任务…...

Spring-Data-Elasticsearch
简介 Spring Data for Elasticsearch 是 Spring Data 项目的一部分,该项目旨在为新数据存储提供熟悉且一致的基于 Spring 的编程模型,同时保留特定于存储的特性和功能。 Spring Data Elasticsearch 项目提供了与 Elasticsearch 搜索引擎的集成。Spring…...

代码随想录二刷7.22|977.有序数组的平方
暴力解法: ——如果想暴力解决这个问题的话,可以像题目那样,先将每一个元素平方,然后再排序 双指针: ——从题目中找到的信息:这是一个非递减顺序的整数数组,从例子中,可以容易看…...

redis介绍与布署
redis remote dictionary server(远程字典服务器) 是一个开源的,使用c语言编写的非关系型数据库,支持内存运行并持久化,采用key-value的存储形式。 单进程模型意味着可以在一台服务器上启动多个redis进程,…...

PMON的解读和开发
提示:龙芯2K1000PMON相关记录 文章目录 1 PMON的发展和编译环境PMONPMON2000 2 PMON2000的目录结构3 Targets目录的组成4 PMON编译环境的建立5 PMON2000的框架6 异常向量表7 Pmon的空间分配8 PMON的汇编部分(starto.S或sbdreset.S)的解读Start.SC代码部分dbginit 9 …...

初识c++(构造函数,析构函数,拷贝构造函数,赋值运算符重载)
一、类的默认函数 默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。 #include<iostream> using namespace std; class Date { public:Date(){_year 1;_month 1;_day 1;cout << _year << "/" <&…...

CANoe:为什么两个VLAN接口不能设置同一个网络的IP地址呢?
经常玩CANoe的人应该配置过TCP/IP Stack中网络节点的网卡信息,基本的信息包含:MAC地址、IP地址、子网掩码、默认网关、MTU值、IPv6地址。 如果你想让发送出去的报文携带VLAN tag,可以在网卡上添加VLAN tag信息。 此时你就能得到两个新的网卡V…...

SpringBoot新手快速入门系列教程七:基于一个低配centoos服务器,如何通过宝塔面板部署一个SpringBoot项目
1,如何打包一个项目 通过IDEA自带的命令行,执行 ./gradlew clean build 2,检查生成的JAR文件 进入 build/libs 目录,你应该会看到一个类似 helloredis-0.0.1-SNAPSHOT.jar 的文件。 3:运行生成的JAR文件 你可以在…...

性能测试的流程(企业真实流程详解)(二)
性能测试的流程 1.需求分析以及需求确定(指标值,场景,环境,人员) 一般提出需求的人员有:客户,产品经理,项目组领导等 2.性能测试计划和方案制定 基准测试: 负觋测试: 压力测试: 稳定性测试: 其他:配置测试…...

使用sklearn的基本流程
scikit-learn,通常简称为 sklearn,是一个开源的Python库,是基于 Python 编程语言的一个非常流行的机器学习库。它建立在 NumPy 和 SciPy 这两个科学计算库之上,并与 Matplotlib 配合使用,为数据预处理、模型训练、评估…...

力扣题解(乘积为正数的最长子数组长度)
1567. 乘积为正数的最长子数组长度 已解答 中等 给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。 一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。 请你返回乘积为正数的最长子数组长度。 本题要求乘积为正数,而整…...

PPTP、L2TP、IPSec、IPS 有什么区别?
随着互联网的发展,保护网络通信的安全越来越重要。PPTP、L2TP、IPSec、IPS是常见的网络安全协议和技术,在保护网络通信安全方面发挥着不同的作用和特点。下面介绍PPTP、L2TP、IPSec、IPS之间的区别。 点对点隧道协议(PPTP)是一种用…...

SpringBoot注解--11--@JSONField @JsonProperty
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一个问题:后端实体类isXXX开头的属性,传到前端后自动去掉is解决方法: JsonProperty和JSONField1.简介2.注解的区别2.1 底层框架不…...

C语言 | Leetcode C语言题解之第221题最大正方形
题目: 题解: int maximalSquare(char** matrix, int matrixSize, int* matrixColSize){int dp[301][301]{0};int wid0;if(matrixSize0&&matrixColSize[0]0){return 0;}for(int i0;i<matrixSize;i){for(int j0;j<matrixColSize[0];j){if(m…...

AI数据服务如何驱使AI商业化,实现在各行业落地融合
AI技术经历数十载的发展,正在加速向各行各业渗透。近年来深度学习加速了人工智能技术的商业化落地的同时,也带来了大量AI算法训练需求,推动AI数据服务市场的快速增长。作为AI快速发展的“基石”,AI数据服务AI数据服务如何驱使AI在…...

户用光伏项目开发流程
1、收集业主信息 管理业主基本信息,包括但不限于联系方式、地址、房屋信息等。 2、业主开卡 每户都需要办理银行卡,用于电费结算和划转。 3、合同签约 业主开卡完成之后,平台方发起签约(支持线上签约),…...

C++ 函数返回值是引用类型使用场景
目录 1、希望返回函数内部的局部静态变量或全局变量 2、希望通过函数返回一个对象的成员变量 3、希望实现链式操作 4、避免对象的拷贝 5、需要注意的事项 在C中,函数的返回值可以是引用类型的情况主要有以下几种: 1、希望返回函数内部的局部静态变…...

CUDA原子操作
代码 #include <cuda_runtime.h> #include <stdio.h>__global__ void atomicAddAndGet(int *result, int *valueToAdd) {// 原子加法int addedValue atomicAdd(result, *valueToAdd);// 通过原子操作后读取值,确保是加法后的值addedValue *valueToAd…...

08.C2W3.Auto-complete and Language Models
往期文章请点这里 目录 N-Grams: OverviewN-grams and ProbabilitiesN-gramsSequence notationUnigram probabilityBigram probabilityTrigram ProbabilityN -gram probabilityQuiz Sequence ProbabilitiesProbability of a sequenceSequence probability shortcomingsApproxi…...

【linux】log 保存和过滤
log 保存 ./run.sh 2>&1 | tee -a /home/name/log.txt log 过滤 import os import re# Expanded regular expression to match a wider range of error patterns error_patterns re.compile(# r(error|exception|traceback|fail|failed|fatal|critical|warn|warning…...

GeoTrust ——适合企业使用的SSL证书!
GeoTrust是一家全球知名的数字证书颁发机构(CA),其提供的SSL证书非常适合企业使用。GeoTrust的SSL证书为企业带来了多重优势,不仅在验证级别、加密强度、兼容性、客户服务等方面表现出色,而且其高性价比和灵活的证书选…...

Kubelet 认证
当我们执行kubectl exec -it pod [podName] sh命令时,apiserver会向kubelet发起API请求。也就是说,kubelet会提供HTTP服务,而为了安全,kubelet必须提供HTTPS服务,且还要提供一定的认证与授权机制,防止任何知…...