MySQL中组合索引需要满足最左匹配原则?

news/2025/2/6 21:53:58/

文章目录

  • ChatGPT解读
  • 证明ChatGPT的结论
  • 总结

mysql的组合索引是KEY idx_nameagenumber ( name, age, number) USING BTREE

SELECT * FROM lianhe_index where name='小米' and age=10 and number=1000;
SELECT * FROM lianhe_index where age=10 and number=1000;
SELECT * FROM lianhe_index where name='小米' and age=10;
SELECT * FROM lianhe_index where name='小米' and number=1000;

ChatGPT解读

这4个SQL都会走索引?

根据您提供的组合索引 KEY idx_nameagenumber (name, age, number) USING BTREE,以下是对每个查询语句是否会使用索引的分析:

  1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND age=10 AND number=1000;
  • 这个查询将会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的所有列。
  1. SELECT * FROM lianhe_index WHERE age=10 AND number=1000;
  • 这个查询也会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的所有列。尽管没有指定 name 列,但索引的顺序是 (name, age, number),所以仍然可以使用索引。
  1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND age=10;
  • 这个查询同样会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的前两列 (name, age)。
  1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND number=1000;
  • 这个查询也会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的第一列和第三列 (name, number)。

总结起来,根据组合索引的定义和查询条件的匹配情况,这四个查询语句都会使用索引 idx_nameagenumber 进行优化。

第2和4不是不符合最左匹配原则?也会使用组合索引?

非常抱歉,我之前的回答有误。根据最左匹配原则,组合索引的列顺序非常重要。在这种情况下,查询语句2和4不会使用组合索引 idx_nameagenumber。

具体分析如下:

  1. SELECT * FROM lianhe_index WHERE age=10 AND number=1000;
  • 这个查询不会使用组合索引 idx_nameagenumber,因为查询条件没有涵盖索引的第一列 name。最左匹配原则要求查询条件必须从索引的最左边开始匹配。
  1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND number=1000;
  • 这个查询同样不会使用组合索引 idx_nameagenumber,因为查询条件没有涵盖索引的第二列 age。同样,最左匹配原则要求查询条件必须从索引的最左边开始匹配。

只有查询语句1和3会使用组合索引 idx_nameagenumber,因为它们的查询条件涵盖了索引的所有列,并且满足最左匹配原则。

非常抱歉给您带来的困惑,感谢您的指正。

确定?语句2和4为什么执行计划explain的key显示使用了合索引 idx_nameagenumber?

非常抱歉给您带来的困惑,我之前的回答是错误的。根据您提供的执行计划 explain 结果,语句2和4确实会使用组合索引 idx_nameagenumber。

这是因为在MySQL中,对于组合索引,如果查询条件涵盖了索引的一部分列,MySQL仍然可以使用该组合索引进行优化。尽管最左匹配原则要求查询条件必须从索引的最左边开始匹配,但如果查询条件涵盖了索引的一部分列,MySQL可以使用这部分索引来加速查询。

因此,在您的情况下,语句2和4的查询条件虽然没有涵盖索引的所有列,但涵盖了索引的一部分列,因此MySQL仍然可以使用组合索引 idx_nameagenumber 进行优化。

组合索引的底层数据不是按字段从左到右建的?

是的,组合索引的底层数据是按照字段从左到右的顺序建立的。这意味着组合索引的第一个字段是最左边的字段,第二个字段是紧随其后的字段,依此类推。

当使用组合索引进行查询时,最左匹配原则要求查询条件必须从索引的最左边开始匹配。这意味着如果查询条件涵盖了索引的前缀,MySQL可以使用该组合索引进行优化。但是,如果查询条件没有涵盖索引的前缀,MySQL将无法使用该组合索引进行优化。

在您提供的例子中,组合索引 idx_nameagenumber 的顺序是 (name, age, number)。因此,查询语句1和3可以使用该索引进行优化,因为它们的查询条件涵盖了索引的前缀。而查询语句2和4虽然没有涵盖索引的前缀,但是由于MySQL可以利用索引的一部分列进行优化,因此仍然可以使用该组合索引

证明ChatGPT的结论

最左匹配原则要求查询条件必须从索引的最左边开始匹配,但如果查询条件涵盖了索引的一部分列,MySQL可以使用这部分索引来加速查询?

mysql> EXPLAIN SELECT * FROM lianhe_index where name='小米' and age=10 and number=1000;
EXPLAIN SELECT * FROM lianhe_index where age=10 and number=1000;
EXPLAIN SELECT * FROM lianhe_index where name='小米' and age=10;
EXPLAIN SELECT * FROM lianhe_index where name='小米' and number=1000;
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
| id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref               | rows | filtered | Extra       |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
|  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 778     | const,const,const |    1 |   100.00 | Using index |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
1 row in set (0.03 sec)+----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
| id | select_type | table        | partitions | type  | possible_keys | key               | key_len | ref  | rows   | filtered | Extra                    |
+----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
|  1 | SIMPLE      | lianhe_index | NULL       | index | NULL          | idx_nameagenumber | 778     | NULL | 100325 |     1.00 | Using where; Using index |
+----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
1 row in set (0.01 sec)+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
| id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref         | rows | filtered | Extra       |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 773     | const,const |    1 |   100.00 | Using index |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
1 row in set (0.01 sec)+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
| id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref   | rows | filtered | Extra                    |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
|  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 768     | const |    1 |    10.00 | Using where; Using index |
+----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
1 row in set (0.03 sec)

通过以上的执行计划,我们来逐个分析下:

  1. SELECT * FROM lianhe_index where name=‘小米’ and age=10 and number=1000;

possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using index,使用了覆盖索引

  1. SELECT * FROM lianhe_index where age=10 and number=1000;

possible_keys=NULL,keys=idx_nameagenumber,rows=100325,Extra=Using where; Using index,没有使用索引,所以才扫描了100325行

  1. SELECT * FROM lianhe_index where name=‘小米’ and age=10;

possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using index,使用了覆盖索引

  1. SELECT * FROM lianhe_index where name=‘小米’ and number=1000;

possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using where; Using index,说明使用了覆盖索引,但还有where条件,而且key_len=768,说明使用了部分索引来加速查询

总结

在使用组合索引的情况下,只要满足最左匹配原则,就会使用到索引,即使查询条件只涵盖了索引的一部分列,MySQL会进行优化,使用这部分索引来加速查询


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

相关文章

2ED2410-EM:12v / 24v智能模拟高侧MOSFET栅极驱动器

概述 12v / 24v智能模拟高侧MOSFET栅极驱动器。 特性 PRO-SIL ISO 26262-准备根据ISO 26262:2018条款8-13支持硬件元件评估的集成商。一个通道器件具有两个高侧栅极驱动器输出。3 Ω下拉,50 Ω上拉,用于快速开关开/关。支持背靠背MOSFET拓扑(共漏极和共源)。两个双向高侧模拟…

深度学习自学笔记十三:unet网络详解和环境配置

一、unet网络详解 UNet(全名为 U-Net)是一种深度学习架构,最初由Olaf Ronneberger、Philipp Fischer和Thomas Brox于2015年提出,用于图像分割任务。该网络的名称来源于其U形状的架构,该架构使得网络在编码和解码过程中…

Vuex存值取值与异步请求处理

目录 前言 一、Vuex简介 1.Vuex是什么 2.Vuex的核心概念 3.使用Vuex的好处 4.Vuex执行流程 二、Vuex的使用步骤 1.安装Vuex 2.创建store模块,分别维护state/actions/mutations/getters 3.使用Vuex存储值,获取值和改变值 1.state.js---存值 2.…

js为什么是单线程?

基础 js为什么是单线程? 多线程问题 类比操作系统,多线程问题有: 单一资源多线程抢占,引起死锁问题;线程间同步数据问题; 总结 为了简单: 更简单的dom渲染。js可以操控dom,而一…

NginxWebUI runCmd 远程命令执行漏洞复现 [附POC]

文章目录 NginxWebUI runCmd 远程命令执行漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 NginxWebUI runCmd 远程命令执行漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相…

SparseBEV:High-Performance Sparse 3D Object Detection from Multi-Camera Videos

参考代码:SparseBEV 动机与主要贡献: BEV感知可以按照是否显式构建BEV特征进行划分,显式构建BEV特征的方法需要额外计算量用于特征构建,而类似query方案的方法则不需要这样做。比较两种类型的方法,前者需要更多计算资…

玉柴集团用USB Server对U盾远程安全管控

在当今数字化时代,企业的业务规模和组织结构日益复杂,对于U盾这样小小的,但却异常重要的USB设备的管理和使用提出了更高的要求。广西玉柴机器股份有限公司作为一家综合性集团企业,其业务规模庞大,组织结构复杂&#xf…

电脑上播放4K视频需要具备哪些条件?

在电视上播放 4K( 4096 2160 像素)视频是很简单的,但在电脑设备上播放 4K 视频并不容易。相反,它们有自己必须满足的硬件要求。 如果不满足要求,在电脑上打开 4K 分辨率文件或大型视频文件会导致卡顿、音频滞后以及更…