mysql左右匹配原则的用法和理解

本文深入探讨MySQL中联合索引的最左匹配原则,并验证其与查询条件顺序无关的特性,通过实例展示不同情况下的索引使用效果。

重点:mysql的最左匹配原则其实是和where后面的查询条件顺序是没有关系的只和索引的字段顺序有关;(这里说的顺序是联合索引的顺序)
这点网上很多地方都说错了

下面我们来用代码模拟一下问题
这里我们创建一个test01表 表中有 abc 三列的复合索引

CREATE TABLE `test01` (
  `id` bigint(25) NOT NULL,
  `a` bigint(255) DEFAULT NULL,
  `b` bigint(255) DEFAULT NULL,
  `c` bigint(255) DEFAULT NULL,
  `d` bigint(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `abc` (`a`,`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  • 对于 回表查询 的测试结果
  1. 按照联合索引的顺序查询结果,可以看到是走了索引的。

在这里插入图片描述

  1. 不按照联合索引顺序查询 ,也是走索引的
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
  2. 不按照索引的顺序查询,是不走索引的
    在这里插入图片描述
    在这里插入图片描述
  • 对于覆盖索引的测试结果
  1. 按照联合索引的顺序查询结果,可以看到是走了索引的。
    在这里插入图片描述

  2. 不按照联合索引顺序查询 ,也是走索引的
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

总结:通过以上的测试可以看到,对于联合索引,查询时 如果走的是回表查询 走不走索引是和where后面的 字段顺序没有关系的只和联合索引的顺序有关;
查询时如果时 覆盖索引 查询,走不走索引就和任何顺序没有任何关系了。

### MySQL 最左前缀匹配原理 最左前缀匹配原则是指在复合索引中,只有当查询条件满足从索引定义的最左侧列开始连续匹配时,才能有效利用该索引[^1]。例如,如果存在一个复合索引 `(col1, col2, col3)`,则以下情况能够触发索引: - 查询条件仅涉及 `col1`。 - 查询条件涉及 `col1` `col2`。 - 查询条件涉及 `col1`, `col2`, `col3`。 但是,如果查询跳过了某个中间列,则无法完全利用此索引。例如,查询条件只涉及 `col2` 或者 `col3` 而不包含 `col1` 的情况下,索引可能部分或者完全失效[^4]。 #### 工作方式 MySQL 在处理查询请求时会尝试按照索引结构来定位数据行的位置。对于复合索引 `(col1, col2, col3)` 来说,存储引擎会在内部构建一棵 B+ 树,其中键值由 `col1`, `col2`, `col3` 组成。B+ 树的特点决定了其查找过程是从根节点到叶子节点逐层比较的过程。因此,为了高效地使用索引,查询条件必须遵循最左前缀的原则,即从索引的第一列开始依次向扩展匹配[^5]。 #### 使用场景 以下是几个典型的使用场景以及注意事项: 1. **单列查询** 如果创建了一个复合索引 `(col1, col2, col3)`,那么单独针对 `col1` 进行过滤操作是可以充分利用这个索引的。这是因为查询条件正好对应于索引的第一个字段[^1]。 2. **多列组合查询** 当查询条件同时包含了 `col1` `col2` 时,仍然可以有效地利用索引来加速检索速度。因为这些条件构成了完整的前缀路径[^3]。 3. **范围查询的影响** 需要注意的是,一旦遇到范围查询(如 `<`, `>`, `<=`, `>=`),后续的所有列都将失去作用。这意味着如果你有这样一个查询语句:`SELECT ... WHERE col1 = ? AND col2 > ? AND col3 = ?` ,虽然 `col1` 可以正常参与索引扫描,但由于 `col2` 是范围条件,所以即使指定了具体的 `col3` 值也无法再进一步缩小搜索空间[^2]。 4. **覆盖索引的应用** 对于某些特定类型的 SQL 请求来说,如果所有的所需信息都可以直接从现有的索引记录里获取出来的话,就不再需要访问实际的数据文件了。这种技术被称为“覆盖索引”,它是提高读取效率的重要方法之一[^3]。 ```sql -- 创建联合索引的例子 CREATE INDEX idx_example ON test(col1, col2, col3); -- 利用覆盖索引减少 IO 开销 EXPLAIN SELECT col1, col2, col3 FROM test WHERE col1=1 AND col2=2; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值