索引不是银弹

数据库索引:不是银弹

  • 使用环境
  • 索引分类
  • 创建索引的代价
  • 最佳实践
  • 不是所有针对索引列的查询都能使用索引加速查询
    • 索引只能匹配列的前缀
    • 条件涉及函数操作的无法使用索引
    • 联合索引只能匹配左边的列
  • 总结

数据库索引是优化性能的良药,但却不是银弹!!!

近日,一同事突然找到我说,xx,我遇见个奇怪的现象的,增加了好几个索引性能竟然没有变化,奇了怪了。我听完后的第一反应是,我不是应该给你写个索引使用攻略啊?!

使用环境

  • MySQL:5.7.24

  • 引擎:InnoDB

索引分类

分类依据索引名称
按存储分聚簇索引
二级索引
按字段特性分主键索引
普通索引
前缀索引
按字段个数分单列索引
联合索引

Tip:InnoDB会自动使用主键作为表的索引键(如果没有主键,就选择第一个不包含 NULL值的唯一列)。

创建索引的代价

任务事物的背后都是有代价的,索引也不例外。创建额外索引的代价主要表现在:

维护代价

对InnoDB存储引擎来说,创建N个索引,就需要创建对应的N颗B+树,新增数据时不光要修改聚簇索引,还要修改这N个二级索引。

空间存储

二级索引不保存原始数据,但是需要保存索引列的数据,索引会占用多余的数据。

Note:SELECT data_length, index_length FROM information_schema.TABLES WHERE table_name=‘TableName’。

回表代价

二级索引不保存原始数据,通过索引找到主键后需要再查询聚簇索引,才能找到需要的数据。

最佳实践

  1. 一开始无需创建太多的索引(除非你确定数据量比较大),等到需要时,比如性能下降,数据量过万,在对具体的场景进行索引优化。

  2. 创建索引后,最好使用explain命令进行验证和确认语句是否真的使用的创建的索引。

  3. 尽量在比较轻的字段上创建索引,比如能索引int字段,就不要索引varchar字段。

  4. 不要忘记了前缀索引,即针对比较长的字段只对前N个字符创建索引。

  5. 尽量不要在生产环境中使用 select * 语句,最好使用查询具体字段。

  6. 查询字段较少并且数据量特别大时,可以考虑使用全部查询字段的联合索引,这样既能实现索引查询加速,又能避免回表操作。

不是所有针对索引列的查询都能使用索引加速查询

我们回到这位同事是问题上来,我们用一个具体的表来模拟他的情况。

CREATE TABLE `person` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) NOT NULL,`score` int(11) NOT NULL,`createTime` timestamp NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

针对表person创建了一个联合索引:

CREATE INDEX name_score ON person(name,score);

索引只能匹配列的前缀

如下图所以,执行计划的type=ALL代表了全表扫描,Extra的值 Using where 也表示使用where语句
explain结果
如下图所以,执行计划的type=range表示走索引扫描,key=name_score 看到实际走了name_score索引
explain结果

条件涉及函数操作的无法使用索引

如下图所以,由于使用了 LENGTH 函数,语句的执行计划type=ALL代表了全表扫描

explain结果

联合索引只能匹配左边的列

这个场景就是同事遇见的场景,虽然对name和score建了联合索引,但是仅按照score列搜索时,InnoDB是无法使用索引的,执行计划给出了结果:

explain结果

其实造成这个的原因也很简单,联合索引是先按照第一列进行排序,第一列相同的数据才会按照第二列进行排序。想让索引跳过第一列,直接使用第二列人眼看也无法解决,还是得按照第二列排序后才能给出合理的答案。问题明确后,解决方案也很简单了:

  1. 只创建针对score列的索引(同事的问题就是使用此方法解决);

  2. 查询条件中加上name字段(很明显这个需要区分场景,这里查询班级分数>80的人,就无法加上name字段了)。

总结

好了,这里就是关于索引的全部内容了,这个故事告诉我们:**不光要使用技术,还要了解一些技术的本质!**祝你技能满满!

Last updated 2024-01-13 06:54:44 +0800

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10-skywalking告警

https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md 5.1:告警指标 ~$ vim /apps/apache-skywalking-apm-bin/config/oal/core.oal service_resp_time # 服务的响应时间 service_sla # 服务http请求成功率SLV,比…

09-Python服务链路追踪案例

skyWalking Python agent requires SkyWalking 8.0 and Python 3.7 # 将django包导入 ~$ cd /apps ~$ tar xf django-test.tgz ~$ cd django-test# 安装模块 ~$ apt install python3-pip ~$ pip3 install -r requirements.txt# 创建django项目mysite ~$ django-admin startpro…

创建一个简单鸿蒙app项目

文章目录 前言TypeScript 基础类型创建一个鸿蒙app总结 一、前言 鸿蒙系统上的开发已经是趋势了,必须紧跟时代的潮流。先简单了解下鸿蒙系统中,我们开发一个app需要用到的语言,那么就是TypeScript。这篇文章主要讲的就是一些基础的语法。最…

HTML+JS + layer.js +qrcode.min.js 实现二维码弹窗

HTMLJSVUE qrcode.min.js 实现二维码生成 引入qrcode.js创建二维码显示位置编写JS 引入qrcode.js <script type"text/javascript" src"https://static.runoob.com/assets/qrcode/qrcode.min.js"></script>创建二维码显示位置 id 作为 定位标识…

docker 安装redis集群,并设置集群密码

一、准备6台机器 二、6台机器分别拉取镜像&#xff1a; docker pull redis三、6台机器分别建立挂载文件夹 mkdir -p /home/redis/data四、6台机器分别执行容器操作 docker run --restartalways -d --name redis-node-1 --net host --privilegedtrue -v /home/redis/data:/da…

算法回忆录——排序

文章目录 1. 插入排序2. 选择排序3. 冒泡排序4. 希尔排序5. 归并排序6. 快速排序7. 堆排序8. 计数排序9. 桶排序10. 基数排序 1. 插入排序 分为两个序列&#xff0c;前面一个序列是排好序的&#xff0c;后面一个序列是未排好的。未排好的序列的第一个元素&#xff08;a&#x…

腾讯云TDSQL TCA/TCP/TCE 认证考试有什么区别呢?

腾讯云认证等级&#xff1a;专项认证考试&云方向认证考试 一、专项认证考试 数据库交付运维-腾讯云TDSQL认证考试一共分为三个等级&#xff1a; 初级TCA、高级工程师TCP、专家级TCE 1、TDSQL TCA培训(MySQL版/PostgreSQL版)考试安排 TCA考试是纯理论题&#xff0c;总分是…

大模型推理优化实践:KV cache 复用与投机采样

作者&#xff1a;米基 一、背景 RTP-LLM 是阿里巴巴大模型预测团队开发的大模型推理加速引擎&#xff0c;作为一个高性能的大模型推理解决方案&#xff0c;它已被广泛应用于阿里内部。该引擎与当前广泛使用的多种主流模型兼容&#xff0c;并通过采用高性能的 CUDA 算子来实现了…

Ubuntu pip换源

在 Ubuntu 上使用 pip 更改软件包的下载源可以通过修改 pip.conf 文件来完成。 首先打开终端&#xff08;Terminal&#xff09;。 输入以下命令创建或编辑 pip.conf 文件&#xff1a; sudo nano /etc/pip.conf如果提示需要管理员密码&#xff0c;则输入密码并按 Enter 键确认。…

出租车费 C语言xdoj697

问题描述 某城市普通出租车计费标准如下&#xff1a; 起步里程为 3 公里&#xff0c;起步费 10 元&#xff1b; 超起步里程后 10 公里内&#xff0c;每公里 2 元&#xff1b; 超过 10 公里以上的部分&#xff0c;每公里加收 50%的回空补贴费&#xff1b; 营运过程中&#xff0c…

大数据技术之Hudi

第1章 Hudi概述 1.1 Hudi简介 Apache Hudi&#xff08;Hadoop Upserts Delete and Incremental&#xff09;是下一代流数据湖平台。Apache Hudi将核心仓库和数据库功能直接引入数据湖。Hudi提供了表、事务、高效的upserts/delete、高级索引、流摄取服务、数据集群/压缩优化和…

1.6用命令得到ip和域名解析<网络>

专栏导航 第五章 如何用命令得到自己的ip<本地> 第六章 用命令得到ip和域名解析<网络> ⇐ 第七章 用REST API实现dynv6脚本(上) 用折腾路由的兴趣,顺便入门shell编程。 第六章 用命令得到ip和域名解析<网络> 文章目录 专栏导航第六章 用命令得到ip和域名解…

【每日小bug】mybatis plus id注解错误导致的问题

插入数据 id不为自增 指定了主键&#xff0c;没有指定自增。会导致出现 修改如上 报错 Data truncation: Out of range value for column ‘id’ at row 1 数据库是bigint&#xff0c;java中是Integer。 修改如上

Day28 17电话号码的字母组合 39组合求和 40组合求和II

17 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 因为输入的数字的数量是不确定的&#xff0c;所以for循环的次数也是不确定的&…

一文读懂Qt信号与槽的机制

Qt的信号与槽主要是为了对象之间的信号传递&#xff0c;以达到某种交互操作的功能。我按照自己的理解逐步实现这样的效果。 步骤一&#xff1a; 第一个类&#xff08;接收者&#xff09;的成员函数实现某种功能&#xff0c;第二个类&#xff08;发送者&#xff09;定义一个对象…

抽象类,接口、代码块、final、单例、枚举

今日内容(记住语法) 抽象类 拥有抽象方法的类就是抽象类。抽象方法&#xff1a;是只有方法签名没有方法体&#xff0c;必须用abstract修饰。抽象类本身也要用abstract修饰的&#xff0c;作用是让子类继承&#xff0c;子类一定要重写抽象方法。模板思想&#xff0c;设计模板模式…

重学Java 3 变量 数据类型转换 运算符

路上难免会有许多挫折&#xff0c;你要学会应对&#xff0c;要坚不可摧 ——24.1.12 一、常量 1.概述&#xff1a;在代码的运行过程中&#xff0c;值都不会发生改变的数据 2.分类&#xff1a; 整数常量&#xff1a;所有整数&#xff0c;包含正负 小数常量&#xff1a;所有带小数…

通过 Elastic Stack 充分利用电信领域生成式 AI 的力量

作者&#xff1a;Elastic Piotr Kobziakowski, Jrgen Obermann 在瞬息万变的电信领域&#xff0c;Elastic Stack 与生成式 AI 的集成正在开创运营效率和创新的新时代。 这些技术不仅增强了网络运营&#xff0c;而且还彻底改变了各个部门的内部流程。 下面&#xff0c;我们将深入…

嵌入式必备的WEB知识

写在前面 嵌入式要学习Wed前端吗&#xff1f;答案是要的&#xff0c;不需要深入学习&#xff0c;只需要简单了解即可。为什么要学习&#xff1f; 原因如下&#xff1a; 可以远程控制和管理设备&#xff1a;通过简单的Web知识&#xff0c;嵌入式系统可以建立Web界面&#xff0c…