MySQL中的最左前缀匹配原则

news/2024/10/24 3:13:07/

最左前缀匹配原则是 MySQL 在使用索引时遵循的一种规则,尤其在涉及到组合索引(联合索引)时。

最左前缀匹配原则指的是在使用组合索引时,MySQL 会从最左边的索引列开始匹配,直到遇到第一个无法继续匹配的列为止。这意味着,如果你想使用组合索引来加速查询,你的查询条件必须遵循 “最左前缀” 的要求,即必须从组合索引最左边的字段开始匹配,逐步向右,不能跳过任何列。


在MySQL中,我们可以为多个字段创建组合索引,例如:

CREATE INDEX idx_user ON users (first_name, last_name, age);

我们为 users 表创建了一个组合索引 idx_user,包含了三个列:first_namelast_nameage。这个索引可以帮助加快查询速度,但是遵循最左前缀匹配的规则,具体体现在以下几个方面:

  1. 完全匹配最左前缀:当你查询条件完全包含最左边的字段,MySQL可以使用这个索引。例如:

    SELECT * FROM users WHERE first_name = 'John';
    

    在这种情况下,查询完全匹配索引中的第一个字段 first_name,因此可以使用 idx_user 索引。

  2. 匹配多个最左前缀的字段:如果查询条件包含索引中前面多个字段,那么MySQL也会使用索引。例如:

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

    这时,查询匹配了 first_namelast_name,MySQL仍然可以使用组合索引 idx_user

  3. 部分前缀匹配:如果查询条件只匹配索引的前几个字段中的一部分,MySQL仍然可以利用索引。例如:

    SELECT * FROM users WHERE first_name = 'John' AND age = 25;
    

    在这种情况下,由于中间的 last_name 被跳过了(而 first_name 后面直接是 age),索引无法很好地工作,只能利用 first_name 的部分匹配部分,而不会利用 age

继续以 users 表和组合索引 (first_name, last_name, age) 为例,看看不同的查询能否使用索引:

  1. 可以使用索引:

    SELECT * FROM users WHERE first_name = 'Alice';
    
    • 只使用了第一个字段,符合最左前缀原则。
    SELECT * FROM users WHERE first_name = 'Alice' AND last_name = 'Smith';
    
    • 使用了前两个字段,符合最左前缀原则。
    SELECT * FROM users WHERE first_name = 'Alice' AND last_name = 'Smith' AND age = 30;
    
    • 使用了所有字段,符合最左前缀原则。
  2. 不能使用索引:

    SELECT * FROM users WHERE last_name = 'Smith';
    
    • last_name 不是最左前缀的第一个字段,MySQL不会使用索引 idx_user
    SELECT * FROM users WHERE age = 30;
    
    • age 不是最左前缀的第一个字段,同样不会使用组合索引。
  3. 部分使用索引:

    SELECT * FROM users WHERE first_name = 'Alice' AND age = 30;
    
    • 这里查询中间跳过了 last_name,只会对 first_name 部分使用索引,而无法有效地对 age 进行索引加速。

LIKE 查询

在进行 LIKE 查询时,最左前缀原则也同样适用。例如,对于一个索引 (first_name)

  • 查询 SELECT * FROM users WHERE first_name LIKE 'A%' 会利用索引,因为查询从最左边开始匹配。
  • SELECT * FROM users WHERE first_name LIKE '%A' 则无法利用索引,因为它并不是从最左边匹配,而是存在前缀通配符。

覆盖索引

在某些情况下,使用最左前缀匹配还可以带来覆盖索引的好处。当所查询的字段全部包含在组合索引中时,MySQL 可以直接通过索引获取结果,而不需要访问数据行。这种现象称为覆盖索引(Covering Index),它可以极大地提高查询效率。例如:

SELECT first_name, last_name FROM users WHERE first_name = 'Alice' AND last_name = 'Smith';

在这个查询中,所有被查询的字段都在索引中,所以可以直接从索引中获取这些数据,而不需要再回到表中读取数据行。


http://www.ppmy.cn/news/1541501.html

相关文章

LeetCode 1750.删除字符串两端相同字符后的最短长度

题目: 给你一个只包含字符 a,b 和 c 的字符串 s ,你可以执行下面这个操作(5 个步骤)任意次: 选择字符串 s 一个 非空 的前缀,这个前缀的所有字符都相同。选择字符串 s 一个 非空 的后缀&#…

linux,socket编程,select,poll,epoll学习

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // 添加这一行 #include <string.h> // 添加这一行 #inc…

Java知识巩固(四)

目录 线程的生命周期 一、新建状态&#xff08;New&#xff09; 二、就绪状态&#xff08;Runnable&#xff09; 三、运行状态&#xff08;Running&#xff09; 四、阻塞状态&#xff08;Blocked&#xff09; 五、死亡状态&#xff08;Dead&#xff09; 什么是双亲委派 …

QGraphics类型学习使用【Qt】【C++】

QGraphics类型学习使用 需求过程全部完整代码 首先已知&#xff0c;QGraphicsView&#xff0c;QGraphicsScene, QGraphicsItem&#xff0c;分别称为&#xff1a;视图&#xff0c;场景&#xff0c;图元&#xff0c;图表就是各种各样的元素&#xff0c;图片元素&#xff0c;线条元…

【橙子老哥】C# 实操分布式事务解决方案

hello&#xff0c;大家好&#xff0c;今天来到橙子老哥的分享时间&#xff0c;希望大家一起学习&#xff0c;一起进步。 欢迎加入.net意社区&#xff0c;第一时间了解我们的动态&#xff0c;文章第一时间分享至社区 社区官方地址&#xff1a;https://ccnetcore.com (上千.net…

【Hive】8-Hive性能优化及Hive3新特性

Hive性能优化及Hive3新特性 Hive表设计优化 Hive查询基本原理 Hive的设计思想是通过元数据解析描述将HDFS上的文件映射成表 基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时&#xff0c;默认将其转换为分布式计算 MapReduce程序对HDFS中的数据进行…

RabbitMQ进阶_可靠性

文章目录 一、 发送者的可靠性1.1、 生产者重试机制1.2、 生产者确认机制1.2.1、确认机制理论1.2.2、确认机制实现1.2.2.1、定义ReturnCallback1.2.2.2、定义ConfirmCallback 二、 MQ的可靠性2.1、 数据持久化2.1.1、 交换机持久化2.1.2、 队列持久化2.1.3、 消息持久化 2.2、 …

HTTP安全么?如何更好的保护您的网站

在互联网飞速发展的今天&#xff0c;网络安全问题日益严峻。HTTP作为最常见的网络通信协议&#xff0c;虽然在传输效率方面表现优异&#xff0c;但其安全性却常常令人担忧。许多企业和个人网站在使用HTTP进行数据传输时&#xff0c;可能忽视了其中潜在的风险。那么&#xff0c;…