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 ...
随机推荐
- Docker容器共享磁盘
需求:.NET程序需要监控一个FTP上的文件变化并进行操作,在linux上使用原生目录时,不管怎么切换后台运行,总是会在一段时间运行后死掉. 方案:远程也不好debug,想了一下,干脆直接使用dock ...
- 爬虫自动化脚本+AI赋能
简介 估计大家对网页爬取和数据抓取已经有所了解,市面上也有许多现成的软件可供使用.例如,前几天群里有位朋友利用爬虫技术抓取了AV网站,并搭建了一个磁力链接站点. 本文将介绍如何模拟手动操作,将一些繁琐 ...
- jenkins异常 -- active (exited),无法启动
一.问题描述 1.无法启动 systemctl start jenkins 没有反应,没有输出报错 2.查询状态 systemctl status jenkins 3.jenkins拒绝访问 二.解决 ...
- Qt/C++摄像头采集/二维码解析/同时采集多路/图片传输/分辨率帧率可调/自动重连
一.前言 本地摄像头的采集可以有多种方式,一般本地摄像头会通过USB的方式连接,在嵌入式上可能大部分是CMOS之类的软带的接口,这些都统称本地摄像头,和网络摄像头最大区别就是一个是通过网络来通信,一个 ...
- Qt音视频开发18-不同视频打开无缝切换
一.前言 在轮询视频的时候,通常都是需要将之前的视频全部关闭,然后打开下一组视频,在这个切换的过程中,如果是按照常规的做法,比如先关闭再打开新的视频,肯定会出现空白黑屏之类的过度空白区间,如何避免这个 ...
- MySql 建表出现的问题 : [ERR] 1064 - You have an error in your SQL syntax; check the manual.......
使用 MySql 建表出现的问题 在使用 Navicat Premium 运行 sql 语句进行建表时,MySQL 报错如下: 1064 - You have an error in your SQL ...
- IM跨平台技术学习(四):蘑菇街基于Electron开发IM客户端的技术实践
本文由蘑菇街前端技术团队分享,原题"Electron 从零到一",有修订和改动. 1.引言 本系列文章的前面几篇主要是从Electron技术本身进行了讨论(包括:第1篇初步了解El ...
- .NET 窗口置于最顶层
本文介绍如何将窗口置于最顶层,以及解决在顶层显示时对锁屏登录界面的影响 一般情况下的窗口置顶,可以设置WPF窗口属性Topmost=true 也可以使用WIN32-SetWindowPos函数SetW ...
- WPF 获取拖拽网页图片链接
在浏览器里拖拽一个元素,我只获取图片链接 private void Grid_PreviewDragOver(object sender, DragEventArgs e) { e.Effects = ...
- C# WebApi 全局配置模型验证和自定义错误处理。config Filters Add ModelStateValidationFilter/CustomExceptionFilter
public static void Start() { logger.Debug("Startup WebAPI..."); SwaggerConfig.Register(); ...