MySQL索引最左原则:从原理到实战的深度解析
MySQL索引最左原则:从原理到实战的深度解析
一、什么是索引最左原则?
索引最左原则是MySQL复合索引使用的核心规则,简单来说:
"当使用复合索引(多列索引)时,查询条件必须从索引的最左列开始,且不能跳过中间的列,否则索引将无法完全生效"
为什么会有这个原则?
这与B+树索引的存储结构密切相关:
- 复合索引按照定义时的列顺序构建
- 数据先按第一列排序
- 第一列相同的情况下按第二列排序
- 依此类推形成层级结构
二、3种典型场景分析
场景1:完美匹配索引顺序
-- 创建索引
CREATE INDEX idx_user ON users(country, city, age);
-- 有效查询
SELECT * FROM users
WHERE country='China'
AND city='Beijing'
AND age=30;
索引使用情况:同时使用三列进行精确查找,走全索引扫描
场景2:缺少最左列
-- 无效查询
SELECT * FROM users
WHERE city='Shanghai'
AND age=25;
索引失效原因:没有最左列country,无法利用索引的排序结构
场景3:中间断档查询
-- 部分有效查询
SELECT * FROM users
WHERE country='USA'
AND age=28;
️ 索引使用情况:仅使用country列进行索引查找,age列无法参与索引过滤
三、5大实战案例分析
案例1:范围查询后的列失效
SELECT * FROM users
WHERE country='Japan'
AND city > 'Osaka'
AND age=35;
索引使用:仅使用到country和city列,age列无法走索引过滤
案例2:LIKE模糊查询
-- 有效情况
SELECT * FROM users
WHERE country='China'
AND city LIKE 'Bei%';
-- 失效情况
SELECT * FROM users
WHERE city LIKE '%hai';
规律总结:只有最左前缀的LIKE查询能使用索引
案例3:覆盖索引特例
-- 查询字段全在索引中
SELECT country, city, age
FROM users
WHERE city='Guangzhou';
特殊机制:虽然不符合最左原则,但通过索引扫描(Index Scan)而非索引查找(Index Seek)完成查询
案例4:排序优化
-- 有效排序
SELECT * FROM users
ORDER BY country, city, age;
-- 失效排序
SELECT * FROM users
ORDER BY city, age;
排序规则:ORDER BY子句同样需要遵循最左原则
案例5:索引跳跃扫描(MySQL 8.0+)
-- MySQL 8.0新特性
SELECT * FROM users
WHERE city='Paris'
AND age=30;
优化机制:通过Index Skip Scan技术突破传统限制,但需要满足:
- 前导列不同值较少
- 优化器认为扫描成本更低
四、最佳实践指南
- 索引设计原则
- 将高区分度的列放在左侧
- 频繁组合查询的列优先
- 避免创建超过3列的复合索引
- 查询优化技巧
-- 反模式
SELECT * FROM table WHERE col2=1 AND col3=2;
-- 优化方案
ALTER TABLE table ADD INDEX idx_col1_col2_col3(col1, col2, col3);
SELECT * FROM table WHERE col1=1 AND col2=1 AND col3=2;
索引分析工具 使用EXPLAIN查看索引使用情况:
EXPLAIN SELECT * FROM users WHERE country='China' AND age=25;
五、常见误区解析
误区1:所有列单独建索引更好
CREATE INDEX idx_country ON users(country);
CREATE INDEX idx_city ON users(city);
CREATE INDEX idx_age ON users(age);
错误认知:
正确做法:分析实际查询模式,建立合适的复合索引
误区2:索引顺序无关紧要
CREATE INDEX idx_city_country ON users(city, country);
错误示例:
正确理解:索引顺序直接影响查询效率,需按查询条件频率排序
误区3:所有查询都能走索引
SELECT * FROM users WHERE city LIKE '%York%';
错误期待:
现实情况:非最左前缀的LIKE查询无法使用索引
六、工具推荐
dblens索引分析工具 提供:
- 可视化索引使用分析
- AI索引设计分析
- 智能索引优化建议
终极口诀:
复合索引像电话,国家城市区号不能差
最左原则要记牢,跳过中间就抓瞎
范围查询是杀手,排序分组也看它
新版优化虽强大,基础规则不能垮
MySQL索引最左原则:从原理到实战的深度解析的更多相关文章
- mysql 索引最左原则原理
索引本质是一棵B+Tree,联合索引(col1, col2,col3)也是. 其非叶子节点存储的是第一个关键字的索引,而叶节点存储的则是三个关键字col1.col2.col3三个关键字的数据,且按照c ...
- MySQL索引最左原则
通过实例理解单列索引.多列索引以及最左前缀原则 实例:现在我们想查出满足以下条件的用户id: 因为我们不想扫描整表,故考虑用索引. 单列索引: ALTER TABLE people ADD INDEX ...
- Mysql索引最左匹配原则
先来看个例子: 1. 示例1:假设有如下的一张表: DROP TABLE IF EXISTS testTable; CREATE TABLE testTable ( ID BIGINT NOT NUL ...
- MySQL索引之数据结构及算法原理
MySQL索引之数据结构及算法原理 MySQL支持多个存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.本文只关注BTre ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
- 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)
在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...
- 【转】mysql索引最左匹配原则的理解
作者:沈杰 链接:https://www.zhihu.com/question/36996520/answer/93256153 来源:知乎 CREATE TABLE `student` ( `id` ...
- mysql索引最左匹配原则的理解
CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `ci ...
- 【转】Mysql索引最左匹配原则理解
作者:沈杰 链接:https://www.zhihu.com/question/36996520/answer/93256153来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- MySQL索引背后的数据结构及原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
随机推荐
- SDK连接节点失败排查思路
https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/faq/connect.html Important: 前置说明 1 ...
- SpringBoot 2.0.0新版和SpringBoot1.5.2版本中Tomcat配置的差别(坑)
2018年春SpringBoot 2.0.0 新版本有了很多新的改变,其中Tomcat配置上也有了很大改变1.之前老的版本TomcatEmbeddedServletContainerFactory取的 ...
- 国外著名交易策略:R-Breaker模型设计原理(转载)
R-Breaker是一种短线日内交易策略,它结合了趋势和反转两种交易方式. 交易系统的基本原理如下: 1.根据前一个交易日的收盘价.最高价和最低价数据通过一定方式计算出六个价位,从大到小依次为:突破买 ...
- P10952 聚会 题解
题目链接 题目大意 对于一棵树,求出一个点对于给定的三个点(以下简称 $x$,$y$,$z$ 且可以重复)距离最短. 题解 对于点的距离,不难想到 LCA 处理.而对于本题,则有两种情况. 第一问 三 ...
- Qt开源作品19-通用数据库翻页查询
一.前言 在Qt与数据库结合编程的过程中,记录一多,基本上都需要用到翻页查看记录,翻页有个好处就是可以减轻显示数据的表格的压力,不需要一次性将数据库表的记录全部显示,也基本上没有谁在一页上需要一次性显 ...
- 不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!
本文由作者小林coding分享,来自公号"小林coding",有修订和改动. 1.引言 说到TCP协议,对于从事即时通讯/IM这方面应用的开发者们来说,再熟悉不过了.随着对TCP理 ...
- 即时通讯安全篇(十一):IM聊天系统安全手段之传输内容端到端加密技术
本文由融云技术团队分享,原题"互联网通信安全之端到端加密技术",内容有较多修订和改动. 1.引言 在上篇<IM聊天系统安全手段之通信连接层加密技术>中,分享了关于通信连 ...
- DateTimeExtensions:一个轻量C#的开源DateTime扩展方法库
推荐一个专门为System.DateTime编写的扩展方法库. 01 项目简介 该项目主要是为System.DateTime和System.DateTimeOffset的编写的扩展方法,包括自然日期差 ...
- 记录实现倒计时的方法,配合按钮的disabled
记录一个自己实现倒计时的方法,现在可以网上有很多插件,自己实现记录一下 // 倒计时 countDown() { this.disabled = true let number = 60 this.c ...
- 记录uniapp上传图片转base64
// 图片转base64 imageToBase64() { return new Promise((reslove, reject) => { uni.getFileSystemManager ...