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)。

关键还是看数据表中的字段及索引情况。

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

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

相关文章

CVE-2024-27292:Docassemble任意文件读取漏洞复现 [附POC]

文章目录 CVE-2024-27292:Docassemble任意文件读取漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 CVE-2024-27292:Docassemble任意文件读取漏洞复现 [附POC] 0x01 前言 …

冒泡排序与其C语言通用连续类型排序代码

冒泡排序与其C语言通用连续类型排序代码 冒泡排序冒泡排序为交换排序的一种:动图展示:冒泡排序的特性总结:冒泡排序排整型数据参考代码(VS2022C语言环境): 冒泡排序C语言通用连续类型排序代码对比较的方式更…

法律行业守护神:知识库+AI大模型,解锁企业知识全周期管理

在法律行业中,搭建一个有效的知识库并进行企业知识全生命周期管理确实是一项不小的挑战。法律环境的复杂性和不断变化的法规要求企业必须持续更新和维护其知识库,以确保所有信息的准确性和实时性。 这种系统化的信息管理不仅有助于提高律师和法律顾问的…

打卡第9天-----字符串

我在自学的时候,看了卡尔的算法公开课了,有些题目我就照葫芦画瓢写了一遍js代码,差不多都写出来了,有暴力解法,有卡尔推荐的思路和方法。话不多说,直接上题上代码吧: 一、翻转字符串里的单词 leetcode题目链接:151. 反转字符串中的单词 题目描述: 给你一个字符串 s…

5个自动化面试题,助你过关斩将!

面试时,自动化是软件测试高频面试内容,通过学习和准备面试题,你会对可能遇到的问题有所准备,从而减轻面试时的紧张感,让你在面试中稳操胜券! 今天,分享一些在面试中可能会遇到的自动化测试面试…

软件架构之测评方法

软件架构之测评方法 第 11 章:测试评审方法11.1 测试方法11.1.1 软件测试阶段11.1.2 白盒测试和黑盒测试11.1.3 缺陷的分类和级别11.1.4 调试 11.2 评审方法11.3 验证与确认11.4 测试自动化11.5 面向对象的测试 第 11 章:测试评审方法 软件测试与评审是…

大学生暑假“三下乡”社会实践工作新闻投稿指南请查收!

近年来,大学生暑期“三下乡”社会实践工作方兴未艾,越来越多的大学生通过参与“三下乡”实践工作,走出校园,深入基层,体验农村生活,服务农民,促进农村经济社会发展,实现了理论与实践…

算能科技,致力于成为全球领先的通用算力供应商

算能致力于成为全球领先的定制算力提供商,专注于RISC-V、TPU处理器等算力产品的研发和推广应用。公司遵循全面开源开放的生态理念,携手行业伙伴推动RISC-V高性能通用计算产业落地;打造覆盖“云、边、端”的全场景产品矩阵,为数据中…

【eNSP模拟实验】三层交换机实现VLAN通信

实验需求 让PC1和PC2能够互相通讯&#xff0c;其中PC1在vlan10中&#xff0c;PC2在vlan20中。 实验操作 首先把PC1和PC2都配置好ip&#xff0c;配置好之后&#xff0c;点击右下角的应用 然后&#xff0c;在S2交换机&#xff08;S3700&#xff09;上做如下配置 #进入系统 <…

mvvm模式

MVVM&#xff08;Model-View-ViewModel&#xff09;模式是一种软件设计模式&#xff0c;特别适用于构建用户界面&#xff08;UI&#xff09;应用程序&#xff0c;尤其是使用WPF&#xff08;Windows Presentation Foundation&#xff09;、Silverlight和其他XAML技术的应用程序。…

【Redis】Redis十大类型

文章目录 前言一、string字符串类型二、List列表类型三、 Hash表四、 Set集合五、 ZSet有序集合六、 GEO地理空间七、 HyperLogLog基数统计八、Bitmap位图九、bitfield位域十、 Stream流10.1 队列指令10.2 消费组指令10.3 ACK机制 前言 redis是k-v键值对进行存储&#xff0c;k…

Mac上pyenv的安装及使用

Mac上pyenv的安装及使用 安装 brew update brew install pyenv 报错 git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallowgit -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow那就执行这2句 还报错 git -C /…

【最经典的79个】软件测试面试题(内含答案)提前备战“金九银十”

001.软件的生命周期(prdctrm) 计划阶段(planning)-〉需求分析(requirement)-〉设计阶段(design)-〉编码(coding)->测试(testing)->运行与维护(running maintrnacne) 测试用例 用例编号 测试项目 测试标题 重要级别 预置条件 输入数据 执行步骤 预期结果 0002.问&…

“论软件维护方法及其应用”写作框架,软考高级论文,系统架构设计师论文

论文真题 软件维护是指在软件交付使用后&#xff0c;直至软件被淘汰的整个时间范围内&#xff0c;为了改正错误或满足 新的需求而修改软件的活动。在软件系统运行过程中&#xff0c;软件需要维护的原因是多种多样的&#xff0c; 根据维护的原因不同&#xff0c;可以将软件维护…

CVE-2024-34351 漏洞复现

CVE-2024-34351&#xff0c;由Next.js异步函数createRedirectRenderResult导致的SSRF。 影响版本&#xff1a;13.4.0< Next.js < 14.1.1 参考文章&#xff1a; Next.js Server-Side Request Forgery in Server Actions CVE-2024-34351 GitHub Advisory Database Gi…

数据库Doris的手动分桶和自动分桶

在Doris中,分桶(Bucketing)是为了更好地管理和查询数据,将数据分成多个小的逻辑单元。分桶可以通过手动或自动的方式进行配置,每种方式各有其特点和适用场景。 Doris 支持两层的数据划分。第一层是分区(Partition),支持 Range 和 List 的划分方式。第二层是Bucket(Tab…

RK3568平台开发系列讲解(内存篇)Linux进程内存的消耗统计

🚀返回专栏总目录 文章目录 一、VSS(Virtual Set Size)二、RSS(Resident Set Size)三、PSS(Proportional Set Size)四、USS(Unique Set Size)五、其他工具Linux 提供了多种进程内存占用的度量指标, 它们反映了不同的内存使用特征: VSS 反映进程虚拟内存总需求, 包括未…

2.python条件语句与循环

1.概述 通过条件语句来判断&#xff0c;条件成立执行某些代码&#xff0c;条件不成立则不执行这些代码 2.if语句 if条件&#xff1a;条件成立执行的代码...... 下方代码没有缩进到if语句块&#xff0c;所以和if条件无关if…else if条件&#xff1a;条件成立执行的代码.....…

Nature Communications|柔性无感智能隐形眼镜(柔性传感/可穿戴电子/柔性电子)

南京大学徐飞(Fei Xu)、陆延青(Yanqing Lu)、陈烨(Ye Chen)和江苏省人民医院袁松涛(Songtao Yuan)团队,在《Nature Communications》上发布了一篇题为“Frequency-encoded eye tracking smart contact lens for human–machine interaction”的论文。论文内容如下: 一、 摘…

常见的load_file()读取的敏感信息

常见的load_file()读取的敏感信息 在编程中或者sql注入时&#xff0c;load_file() 函数通常用于读取文件内容&#xff0c;而敏感信息的泄露往往是由于不当的使用这个函数或缺乏足够的安全措施。下面是一些常见的敏感信息及其可能的具体位置&#xff1a; 配置文件&#xff1a; …