最左前缀法则

概念

  1. 最左前缀法则是针对于复合索引而言的,也就是说一个索引有多个字段
  2. 那么索引的查询从最左列开始,并且不跳过索引的列,如果跳过索引中的某一列,那么,会导致索引部分失效(跳过列之后的索引失效)
  3. 如果出现了范围查询(>,<),那么会导致索引列后的索引失效

栗子

建表

CREATE TABLE IF NOT EXISTS `article` (
`id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`author_id` INT(10) UNSIGNED NOT NULL,
`category_id` INT(10) UNSIGNED NOT NULL,
`views` INT(10) UNSIGNED NOT NULL,
`comments` INT(10) UNSIGNED NOT NULL,
`title` VARBINARY(255) NOT NULL,
`content` TEXT NOT NULL
);
 
INSERT INTO `article`(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) VALUES
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');
 
SELECT * FROM article;

例题一

查询 category_id 为1 且 comments 等于 1 的情况下,views 等于1 article_id

没有索引

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments =1  AND views = 1;

查询的执行结果为

+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | article | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+

我们可以看到他的执行计划,type为all,也就是全表扫描

复合索引

这个时候我们新建一个索引

CREATE INDEX idx_article_ccv ON article(category_id,comments,views);

全值匹配

再次执行

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments =1  AND views = 1;

执行计划为

+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys   | key             | key_len | ref               | rows | filtered | Extra |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+
|  1 | SIMPLE      | article | NULL       | ref  | idx_article_ccv | idx_article_ccv | 12      | const,const,const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------------+------+----------+-------+

我们可以看到这次的type是ref,走的索引为idx_article_ccv,也就是我们刚刚新建的索引,索引的长度为 12

and顺序

我们把执行的sql改为

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND views = 1 AND comments =1  ;

我们可以发现他的执行计划一点没有变,也就是说与and的顺序无关

去掉views

我们去掉查询字段views,执行sql语句

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments =1;

执行计划如下

+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys   | key             | key_len | ref         | rows | filtered | Extra |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------+------+----------+-------+
|  1 | SIMPLE      | article | NULL       | ref  | idx_article_ccv | idx_article_ccv | 8       | const,const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------------+------+----------+-------+

我们可以看到结果key_len变成了8,没有全部走索引的列,能得出view的key_len为4

去掉views和comments

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 ;

执行计划为

+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys   | key             | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | article | NULL       | ref  | idx_article_ccv | idx_article_ccv | 4       | const |    2 |   100.00 | NULL  |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-------+

我们会发现他的key_len变成了4,也就是说能得出view的key_len为4,comments的key_len为4,category_id key_len也为4

上面的查询完全根据最左前缀,没有跳过索引中的列

例题二

以例题一为基础,我们跳过一个索引列,

中间列

跳过comments的这个列进行查询

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND views = 1;

执行计划如下

+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys   | key             | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | article | NULL       | ref  | idx_article_ccv | idx_article_ccv | 4       | const |    2 |    33.33 | Using index condition |
+----+-------------+---------+------------+------+-----------------+-----------------+---------+-------+------+----------+-----------------------+

我们会发现他的key_len为4,也就是说只走了最左列的category_id 这个索引列

跳过最左列

跳过category_id 查询,我们运行下面的sql

 EXPLAIN SELECT id,author_id FROM article WHERE comments =1  AND views = 1;

执行计划为

+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | article | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+

我们会发现他完全再走全表扫描

例题三

范围查询,以例题一为基础,查询comments大于1的

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND views = 1 AND comments > 1  ;

执行计划如下

+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys   | key             | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | article | NULL       | range | idx_article_ccv | idx_article_ccv | 8       | NULL |    1 |    33.33 | Using index condition |
+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+

我们会发现他的key_len为8,views的索引列失效了,这个范围查询导致了索引的失效,但是我们只要把>加上一个等号,就会发现views索引可以使用了

 EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND views = 1 AND comments >= 1

执行计划如下

+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys   | key             | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | article | NULL       | range | idx_article_ccv | idx_article_ccv | 12      | NULL |    2 |    33.33 | Using index condition |
+----+-------------+---------+------------+-------+-----------------+-----------------+---------+------+------+----------+-----------------------+

原理

数据库中的索引是以Btree来进行存放的,其特点是定位高效、利用率高、自我平衡,特别适用于高基数字段,定位单条或小范围数据非常高效。

理论上,使用Btree在亿条数据与100条数据中定位记录的花销相同。

如下为插入数据的过程
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/318857.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习redis有效期和数据类型

1、安装redis和连接redis 参考&#xff1a;ubuntu安装单个redis服务_ubuntu redis单机版安装-CSDN博客 连接redis&#xff1a;redis-cli.exe -h localhost -p 6379 -a 123456 2、Redis数据类型 以下操作我们在图形化界面演示。 2.1、五种常用数据类型介绍 Redis存储的是key…

数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)六

第三部分、栈(Stack)和队列(Queue)详解 栈和队列&#xff0c;严格意义上来说&#xff0c;也属于线性表&#xff0c;因为它们也都用于存储逻辑关系为 "一对一" 的数据&#xff0c;但由于它们比较特殊&#xff0c;因此将其单独作为一章&#xff0c;做重点讲解。 使用栈…

UISegmentedControl控件定制

1.在xib中设计如下: 背景颜色: 段标题与数量 : 2.在代码中控制 关联控件 注册控件事件 控件事件处理函数实现: 定制Title颜色 4 --- > UIControlStateSelected 0 --- > UIControlStateNormal 最终实现效果: 取控件选中时的索引与显示文本: 输出:

我在代码随想录|写代码Day7之454.四数相加II ,​ 383. 赎金信​,​ 15. 三数之和​

454.四数相加II 题目 解题思路 四个数字相加的和为0,我们要选俩数组,让他们的笛卡尔积储存在哈希表中,然后我们要找的是这俩数和的相反数,然后就是将后面俩数组相加在后面的数组和中找相反数. 383. 赎金信 解题思路 题目意思是让在字符串1中找到字母组成字符串2所以找字符串1…

Sentinel微服务保护

文章目录 Sentinel微服务保护1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.解决方案1.1.3.总结 1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel 1.4.微服务整合Sentinel 2.流量控制2.1.簇点链路2.1.快速入门2.2.流控模式2.2.1.…

【C++】wxWidgets库实现窗体程序

一、安装wxWidgets库 在Debian系统上使用wxWidgets库来创建一个基本的窗体程序&#xff0c;首先需要确保已经安装了wxWidgets相关的库和开发工具。下面是安装wxWidgets的步骤&#xff1a; 打开终端&#xff0c;使用下述命令安装wxWidgets库及其开发文件&#xff1a; sudo ap…

Tomcat解压打包文件和并部署

一、文件压缩和上传解压 1.本地打包好dist.tar.gz文件 2.通过xftp拖拽上传到知道文件夹下,或者通过命令: cp dist.tar.gz /path/to/destination/folder注:将dist.tar.gz复制到 /path/to/destination/folder文件夹下,该文件夹只是举个例子怎么复制和解压! 3.进入/path/…

ENNOID-BMS从控板分析-基于LTC6813的版本

LTC6813简单说明 单体电压采集部分&#xff0c;总共可以采集18个电芯电压&#xff0c;这18个电压分别交给3个16位Delta-Sigma ADC来进行采样&#xff1b;官方手册宣称的采样误差低于2.2mV&#xff0c;采样范围为0~5V&#xff0c;所有18个电芯采样一次只要290uS时间。电压均衡部…

Python中的列表跟C/C++里面的数组什么关系?

你好&#xff0c;我是安然无虞。 文章目录 Python数据类型列表创建列表新增列表元素append方法insert方法 删除列表元素pop方法remove方法 查找列表元素in相关index方法 下标访问列表元素负索引 遍历列表元素子列表提取拼接列表 相关extend方法 列表常用接口汇总列表操作列表的…

SpringCloud Aliba-Nacos-从入门到学废【1】

&#x1f95a;今日鸡汤&#x1f95a; 当你最倒霉地时候一定要扛住。 因为&#xff0c;那正是你运气该上升的时候。 ——《一人之下》 目录 &#x1f9c8;1.Nacos介绍 &#x1f9c2;2.Nacos服务提供者注册 &#x1f953;3.Nacos服务消费者 &#x1f32d;4.Nacos作为配置中心…

双目测距工程Stereo-Vision-master学习笔记

硬件&#xff1a; 首先要要把两个摄像头固定到支架上&#xff0c;并且两个摄像头的间距应该在110mm&#xff0c;两个摄像头没有落差 相机的内参数包括焦距、主点坐标、像素尺寸等&#xff0c;这些参数决定了相机成像的几何变换关系。内参数是相机固有的属性&#xff0c;不会随…

Bean作用域及生命周期

关于Bean对象&#xff0c;在将其存储到spring中以后&#xff0c;在使用或读取该Bean对象时&#xff0c;如果该对象是公有的&#xff0c;难免就会出现被一方修改&#xff0c;从而影响另外一方读取到的对象准确性的情况。因此了解Bean的作用域和生命周期就是十分必要的了。 首先…

2024年AMC8模拟考试实测流程、注意事项和常见问题

和往年的AMC8比赛一样&#xff0c;在正式比赛的前一周左右会开放两天的模拟考试时间&#xff0c;AMC8的主办方建议所有的参赛选手重视且参加模拟考试&#xff0c;以测试设备、熟悉流程&#xff0c;避免将来正式考试不小心违规&#xff0c;或者设备不给力。 2024年的AMC8模拟考…

Matlab字符识别实验

Matlab 字符识别OCR实验 图像来源于屏幕截图&#xff0c;要求黑底白字。数据来源是任意二进制文件&#xff0c;内容以16进制打印输出&#xff0c;0-9a-f’字符被16个可打印字符替代&#xff0c;这些替代字符经过挑选&#xff0c;使其相对容易被识别。 第一步进行线分割和字符…

一个简易的PHP论坛系统

一个简易的PHP论坛系统 php课程设计&#xff0c;毕业设计 预览 技术 bootstrap 4.x jquery css php mysql 5.7 目录结构 登录 管理员 admin/123456 测试用户 user1/123456 更多文章和源码获取查看

MongoDB认证考试小题库

Free MongoDB C100DBA Exam Actual Questions 关于MongoDB C100 DBA 考试真题知识点零散整理 分片架构 应用程序 --> mongos --> 多个mongod对于应用来说&#xff0c;连接分片集群跟连接一台单机mongod服务器一样分片好处&#xff0c; 增加可用RAM、增加可用磁盘空间、…

【Spring Cloud Alibaba】Sentinel 服务熔断与流量控制

目录 前言 一、Sentinel 入门 1.1 什么是 Sentinel ? 1.2 微服务集成 Sentinel 1.3 安装Sentinel控制台 二、Jmeter 压力测试工具 2.1 Jmeter 介绍 2.2 Jmeter 安装 2.3 接口测试 三、Sentinel 使用 3.1 限流规则 3.1.1 warm up(预热模式) 3.1.2 排队等待 3.1.3…

记redis5.x在windows上搭建集群(六主六从)

六个运行端口 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 1、安装redis,文章太多不多BB 2、复制六份redis文件夹出来改名 3、修改每一份的配置文件 redis.windows.conf 修改为以下格式&#xff1a; #运行端口 port…

线性代数——(期末突击)概率统计习题(概率的性质、全概率公式)

目录 概率的性质 题一 全概率公式 题二 题三 概率的性质 有限可加性&#xff1a; 若有限个事件互不相容&#xff0c;则 单调性&#xff1a; 互补性&#xff1a; 加法公式&#xff1a; 可分性&#xff1a; 题一 在某城市中共发行三种报纸&#xff1a;甲、乙、丙。在这个…

vue3实现动态侧边菜单栏的几种方式总结

基于自建json数据的动态侧边菜单栏 后端接口json数据 src/api/menuList.js const menuList [{url: ,name: 人员管理,icon: icon-renyuan,menuId: 1,children: [{url: /user,name: 用户管理,icon: icon-jurassic_user,menuId: 1001,children: []},{url: /role,name: 角色管…