秋招突击——7/9——MySQL索引的使用

文章目录

    • 引言
    • 正文
      • B站网课
        • 索引基础
        • 创建索引
        • 如何在一个表中查看索引
        • 为字符串建立索引
        • 全文索引
        • 复合索引
        • 复合索引中的排序问题
        • 索引失效的情况
        • 使用索引进行排序
        • 覆盖索引
        • 维护索引
      • 数据库基础——文档资料学习整理
        • 创建索引
        • 删除索引
        • 创建唯一索引
        • 索引提示
        • 复合索引
        • 聚集索引
        • 索引基数
        • 字符串前缀索引
        • 索引顺序
        • 对索引的隐式类型转换
      • 索引下推
      • 结合面试题回顾
        • 如何避免索引失效
        • 如何优化索引
    • 总结

引言

  • 今天怎么都得看完,不然项目都没时间整了,简历这周怎么都得搞完,不然肯定得挂!不行!
  • 这里重在于讲述索引的东西,先回顾一下索引基础知识、然后就是索引的原理以及如何设计索引才能更加高效。
  • 数据来源主要有两部分,分别是
    • B站的SQL进阶教程
    • 数据库教程网站

正文

B站网课

索引基础
  • 索引是能够提高数据库从表中检索数据行的速度的一种数据结构,但是需要额外的写入和存储来维护

    • 查询优化器,可以使用索引来快速定位数据,不需要全表逐行扫描
  • 索引很小,大部分都是保存在内存中的,所以,从内存中读取数据总是比磁盘中读取数据来得快
    *
    索引的代价

  • 增加数据库空间消耗,作为数据库的一部分,会一直和表格一块保存

  • 每次增删改都需要的维护更新索引

综上

  • 为性能关键的查询保留索引,需要基于查询创建索引,主要是为了加快部分查询十分缓慢的查找。
创建索引
  • 通过Explain关键字查看是否使用了索引,主要是通过Type关键字和row关键字查看
    • type是使用的索引类型
    • row是查询的行数
      在这里插入图片描述
      创建索引,加速查询的过程
create index idx_state on table_name(col_name);
  • possible_keys
    • 在查询过程中,可能用到的索引,这里是使用了idx_state,如果是联合查询,会是多个索引值
  • key
    • 在实际查询中,所使用索引或者键,上面那个是可能使用的,下面那个是实际使用的
      在这里插入图片描述
select customer_id  from customers where points > 100;   // 选择所有分数大于100的顾客的id
create index idx_points on customers(pointers);     // 对customer表格的pointer列创建索引

在这里插入图片描述

如何在一个表中查看索引
show indexes in customers;

在这里插入图片描述

  • 聚簇索引
  • 二级索引
    • 每一次创建一个二级索引,都会自动将主键索引加入到对应二级索引中
    • 二级索引:二级索引字段 + 主键索引
为字符串建立索引
  • 主要是为
    • char、varchar、text和blob创建索引
    • 这类索引会占据大量空间,无法达到很好的性能。所以,这里要尽量包含字符串的前几个字母,也就是前缀。

创建一个长度为20的前缀索引

  • 创建针对customers表格的last_name列的前二十个字符构成的字符串
create index idx_lastname on customers (last_name(20));
  • 这个长度选择,要能偶尽可能在短的情况下,遍历到所有的数据
全文索引
  • 查询文章或者题目中和“react redux”相关的所有的posts,下述方法存在一些问题
    • 随着数据库越来越大,搜索的范围越大,时间越慢
    • 全表扫描,没有索引
      在这里插入图片描述
      创建全文索引==》实现模糊查询,像搜索引擎一样
# 创建全文索引
create fulltext index on table_name(col_A,col_B);
# 使用全文索引
select *
from table_name 
where match(col_A,col_B) against ('这里输入相关的关键字');

在这里插入图片描述

  • 相关性得分
    • MySQL会基于若干因素,为包含了搜索短语的每一行计算相关性得分,是0到1之间的浮点数。

全文索引的两种方式

  • 自然语言模式,默认模式,就是上文使用模式
  • 布尔模式,包括或者是排除某些单词
    • 下述使用的布尔模式,查询包含了react和form,但是不包含redux 关键字的。
      在这里插入图片描述
复合索引
  • 找到位于加州并且收入大于8000的,这里加州和收入是两张表里面的数据
# 这里是做了一个连表查询
select customers_id from customers where state ='CA' and points > 1000;
  • 具体执行过程
    • 因为只用到一个索引,所以就是先找到所有州为CA的用户,然后在查询这些用的points
    • 因为只用到了一个索引,如果能够CA里面是有points >1000的索引,就快很多了。这就是联合索引的作用
      在这里插入图片描述
  • 对于州和point两个列建立联合索引,然后能够通过州和point快速访问到目标
create index idx_state_points on customers(state,points);

在这里插入图片描述

补充

  • 复合索引如果匹配到的范围查找,就不走索引了,后续会走索引下推
  • 复合索引的最左匹配原则,不是说顺序,是说具体的值,where a and b and c 对于索引(a,b,c)是满足最左匹配原则的,但是如果是where c and b就不满足了,因为少了一个。
复合索引中的排序问题

遵循以下两个原则

  • 使用最频繁的列放在前面
    • 将使用最频繁的放在前面,能够有效缩减搜索范围
  • 将基数最高的放在前面
    • 可以将总得样本,划分成数量跟少的样本,前面的搜索的范围会更小
  • 关注查询本身,根据查询本身进行优化,尽量缩减问题搜索的空间

在州和用户姓氏两个关键字上创建一个联合索引

create index idx_lastname_satte on customer(last_name,state);
  • 下述是last_name在前,state在后,扫描的列是40
    在这里插入图片描述
  • 下述是使用州在前,然后姓氏在后,仅仅查询了两行,效率更好
    在这里插入图片描述
索引失效的情况
  • 下述是使用or进行索引联合,通过explain可以看到,是查询了1010个数据,相当于全表扫描

  • 下述是使用union将两个子索引查询进行拼接,总共扫描了660个数据,远远小于第一个索引拼接方式

在这里插入图片描述

调用列进行了相关的运算
在这里插入图片描述

  • 下述进行了数字迁移,然后扫描量变成了3,因为虽然使用了比较函数,但是并没有调用对应对的列进行运算

在这里插入图片描述

使用索引进行排序
  • 添加索引的时候,MySQL会获取该列中的所有的值,并对结果进行排序,并将他们存储在索引中

在这里插入图片描述

使用没有对应索引的列进行排序==》产生外部排序,外部排序十分耗时,通过下图可以看到外部排序的时间耗费是第一个时间复杂度的10倍using filesort关键字进行排序

  • 下述做的排序是一个全标扫描,进行的排序
    在这里插入图片描述
  • 正常情况下,如果你要对数据进行排序,而且使用的是联合索引的中的两个列,那么必须要按照的相同顺序或者相同的升降顺序进行查询和排序的,否则会增加消耗时间。
    在这里插入图片描述
    特殊情况:一定要按照的联合索引的列进行排序查询,否则就会出现对应的全表扫描
  • 因为建立联合索引的时候,实现按照第一个列state进行分类的,然后在同一个state中,是按照points进行排序的。现在要直接points进行全部排序,就用不到索引了。
    在这里插入图片描述
    在这里插入图片描述
覆盖索引
  • 下述是覆盖索引,需要查询的数据在索引中就存在,不需要在会表进行查询即可获得,效率很高。这种现象就是索引覆盖!
  • select子句中查看的所有的数据列,都在索引中,就不需要在通过回表进行查询,这就是索引覆盖
    在这里插入图片描述
维护索引
  • 重复索引:相同列的不同顺序(A,B,C)和(B,A,C)
  • 多余索引:索引重复的情况,A和(A,B)

数据库基础——文档资料学习整理

创建索引

索引的定义

  • 索引是一种能够加快数据检索的数据结构,但是需要额外的写入和存储来维护
  • 查询优化器能够通过索引,快速定位数据,不必扫描表中的每一行
  • 索引本身和数据一起存储在同一表中

聚簇索引和非聚簇索引

  • 聚簇索引
    • 使用主键或者唯一键创建表的时候,会自动创建一个名为primary的索引
  • 非聚簇索引
    • 二级索引或者非聚簇索引是除了聚簇索引以外的索引。

创建索引的语法

CREATE [UNIQUE] INDEX index_name
[USING {BTREE | HASH}]
ON table_name (column_list)
[algorithm_option | lock_option];
  • 使用explain来查看对应的SQL执行情况
    在这里插入图片描述
  • 查看当前已经创建的索引

在这里插入图片描述

删除索引
  • 索引需要有空间代价和时间代价,所以需要删除
drop index index_name on table_name;

在这里插入图片描述

创建唯一索引
  • 虽然已经有了主键索引唯一索引,但是有的时候,还是需要创建自增的数字列,比如说订单表中的订单编号,用户表中的电子邮件等
create unique index index_name on table_name (col_name);

在这里插入图片描述

索引提示
  • MySQL的查询优化器为SQL语句制定最佳执行计划,根据索引基数进行决策,有的时候,你创建了索引但是没有使用也是因为索引基数不对。
  • 使用use index强制sql语句建议查询优化器使用指定的索引。
SELECT column_list
FROM table_name
USE INDEX (index_list)
WHERE condition;
复合索引

定义

  • 复合索引又称为组合索引或者是多列索引,最多能够创建16个列

创建语法

CREATE INDEX index_name
ON table_name(column_1, column_2, column_3);

复合索引规则

  • 将where子句中常用的列放在索引列列表的开头
  • 将不常用的列放在索引列列表的后面

MySQL总是按照最左匹配的原则展开对应的查询语句

CREATE INDEX index_name
ON table_name(a, b, c);
  • 在上述索引的情况下,如果查询使用的是下述顺序都会使用对应的索引,a先满足了,然后在去看b
WHERE a = v1 and b = v2 and c = v3;
WHERE a = v1 and b = v2;
WHERE a = v1;
  • 如果是下述情况,就不会使用对应的索引
WHERE b = v2 and c = v3;
WHERE c = v3
聚集索引

定义

  • 聚集索引是一种特殊的索引,该索引中的键值顺序决定了表中相应行的物理顺序。
  • 表格中的数据,只能按照一种顺序进行存储,所以表中只能有一个聚集索引。

InnoDB中的MySQL聚集索引

  • 如果指定了主键,主键就是聚集索引
  • 如果没有逐渐,第一个非空的列,并且是Unique的列,就是聚集索引
  • 如果没有合适的,MySQL会在内部生成一个隐藏的聚集索引。
  • InnoDB中二级索引中的每条记录都包含该行的主键列和非聚集索引指定的列
索引基数

定义

  • 一个索引的基数,就是这个索引列中唯一值的数量
    • 是根据统计信息生成的估计值,并不准确
  • 是查询优化器决定是否索引的依据,基数越高,索引越有效!
  • 基数越低,索引越无效,还不如全表扫描

查看索引基数

show indexes from table_name;

在这里插入图片描述

字符串前缀索引

定义

  • 为字符串列创建前缀索引,
  • 相比于对整个字符串创建索引,前缀索引能够减少磁盘的使用量,提高索引的写入速度

具体语法

create index idx_name on table_name (col(prefix_length));
  • 如果你使用对应的where的部分匹配,如果这对对应的字段创建了前缀索引就会使用对应索引加快速度,而不是全局扫描
select  * from table_name where first_name like 'ge%';
索引顺序

定义

  • 在创建索引的时候,指定索引的顺序,默认情况下,是按照升序存储的。
CREATE [UNIQUE] INDEX index_name
[USING {BTREE | HASH}]
ON table_name (column_name [ASC | DESC], ...)
[algorithm_option | lock_option];
对索引的隐式类型转换
  • 如果索引字段是字符串类型,但是在条件查询中,输入的参数是整型的话,会走全表扫描
    • 如果索引字段是 整型类型,查询条件中输入的参数是字符串,不会导致索引失效的

MySQL在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后在进行比较

  • 自动类型转换是函数操作,CAST操作
# 下述两个SQL语句是等价的
select * from t_user where phone = 1300000001;
select * from t_user where CAST(phone AS signed int) = 1300000001;  # 这里是对phone进行了函数操作
# 下述的SQL语句会使用索引进行扫描,因为是将输入的参数的进行类型转换,而不是将索引进行类型转换
select * from t_user where id = "1";
select * from t_user where id = CAST("1" AS 1);

索引下推

这部分的所有资料都是来自这个链接——五分钟搞懂MySQL索引下推
定义

  • 能够减少回表查询的次数,提高查询的效率
  • 将部分上层也就是服务层负责的事情,交给下层引擎层去处理
  • 通过Extra中using index condition来进行判定

原理

  • 没有索引下推的情况

    • 存储引擎读取索引记录
    • 根据索引中的主键值,定位并读取完整的行记录。
    • 存储引擎吧记录交给Server层,检测记录是否满足Where子句条件
  • 有索引下推的情况

    • 存储引擎读取索引记录
    • 新增操作:判断where条件部分能够用索引中的列来检查,条件不满足,就处理下一行索引记录
    • 条件满足,使用索引中的之间,去定位并读取完整的行记录,也就是回表
    • 存储引擎吧记录交给Server层,检测记录是否满足Where子句条件

具体执行实例

  • 这里已经建立了联合索引,会按照最左匹配的原则,先查的name然后就是age
select * from tuser where name like '张%' and age = 10;
  • 没有ICP的时候

    • 数据引擎仅仅会使用第一个索引,返回所有姓张的列,然后由server层进行过滤,每一个姓张的样本都会进行回表查询,效率低
  • 有ICP

    • 数据引擎会在底层同时使用两个索引,查找到姓张的行后,会对年龄进行判定, 减少了回表的次数,效率比较高!

这里还是看一下原来的链接更容易理解

索引下推使用的条件

  • 只能用于range、ref、eq_ref、ref_of_null访问方法
  • 对于InnoDB来说,只能用于二级索引
  • 使用子查询的条件不能下推
  • 引用了存储函数条件的不能下推

具体应用场景

  • 联合索引在遇到范围查询时,会停止匹配,后续的字段就不会在使用
select * from t_user where age >20 and reward = 10;
  • 有了索引下推之后,即使reward无法走索引,但是在二级索引里面,会在存储引擎中进行过滤,减少回表次数

结合面试题回顾

如何避免索引失效

个人学完之后的回答

  • 不要使用or语句,如果是or的话,建议拆成多个不同的语句进行拼接
  • 不要对创建索引的列加上对应的运算,比如说加减乘除等,col + 2 > edge,不如改成 col > edge -2;
  • 如果是联合索引,在where子句中,一定要先先使用满足最左列,然后依次往后
  • 尽量使用基数比较大的索引。

参考回答

  • 使用左或者左右模糊匹配的时候,会造成索引失效,比如说like %xxx 或者 like %xxx%
  • 在查询条件中对索引列做了计算、函数、类型转换的操作,会造成索引失效的。
  • 联合索引要遵循最左匹配原则,按照最左有限的方式进行索引匹配,否则会导致索引失效。
  • 使用where子句时,or的前列是索引列,后列不是索引列,索引会失效
如何优化索引
  • 在创建联合索引的时候,观察select对应列,尽量创建覆盖索引,避免回表,减少大量的IO操作性能。
  • 防止索引失效,尽量不要写会让索引失效的SQL语句
  • 主键索引最好是单调递增的值
    • 主键是随机的值,插入会引起页分裂现象,导致大量的内存碎片
  • 对于大的字符串索引,考虑使用前缀索引只对前缀部分简历索引,节省索引的存储空间。

总结

  • 如果我在面试拼多多之前,就把这个东西整理了,或者说看了,也就不会那么尴尬,现在已经去实习了,很难顶!
  • 不过等到秋招的正式批,这个问题应该是难不倒我了,看一下,回顾一下就行了!
  • 加油吧!整理这个的时候,满心都是后悔,下次不能让这种事情发生!

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

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

相关文章

git 笔记

文章目录 前言一些代码托管仓库初步的一些理解设置个人信息创建自己的仓库查看仓库的状态添加文件到暂存区把暂存区的文件添加到版本库查询两个文件之间的区别查看版本迭代信息版本回滚查看所有的历史版本快捷切换应用感受分支的一些相关的操作假设新建一个分支并跳转到这个分支…

【ARM】MDK安装ARM_compiler5无法打开安装程序

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 在客户安装了最新版本的MDK5.37及后续更新版本,但原工程使用ARM_Compiler_5.06进行编译和调试,需安装ARM_Compiler_5.06的编译器版本,但在解压缩的过程中后续无法打开ARM_Compiler…

FinalShell介绍,安装与应用

目录 一、什么是finalshell 二、finalshell功能 三、为什么要用finalshell 四、安装finalshell 五、finalshell使用 1.添加连接 获取虚拟ip地址 2.启动连接 一、什么是finalshell FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(四)-无人机系统(UAS)命令与控制(C2)通信用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…

Re:从零开始的C++世界——(一)入门基础

文章目录 C发展历史1.命名空间1.1 namespace的价值1.2 namespace的定义1.3 命名空间使⽤ 2.C输⼊&输出3.缺省参数3.1 缺省参数的概念3.2 缺省参数的分类 4.函数重载5.引⽤5.1引⽤的概念和定义5.2 引⽤的特性5.3 const引⽤5.4 使用场景5.5 指针和引⽤的关系 6.内联函数6.1内…

NAT地址转换+多出口智能选路,附加实验内容

本章主要讲:基于目标IP、双向地址的转换 注意:基于目标NAT进行转换 ---基于目标IP进行地址转换一般是应用在服务器端口映射; NAT的基础知识 1、服务器映射 服务器映射是基于目标端口进行转换,同时端口号也可以进行修改&…

Mybatis-plus 集成 PostgreSQL 数据库自增序列问题记录

1.创建序列并绑定id CREATE SEQUENCE biz_factory_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;"id" int4 NOT NULL DEFAULT nextval(sys_user_seq::regclass), 2.实体设置KeySequence和TableId注解 注意IdType.INPUT 和 KeySequence(value …

Java巅峰之路---基础篇---综合练习(面向对象)

目录 文字版格斗游戏 基础版 souf输出语句 进阶版 键盘录入的说明 复杂对象数组练习 需求: 添加和遍历 删除和遍历 修改和遍历 文字版格斗游戏 基础版 格斗游戏,每个游戏角色的姓名,血量,都不相同,在选定人…

c++入门基础篇(上)

目录 前言: 1.c++的第一个程序 2.命名空间 2.1 namespace的定义 2.2 命名空间使用 3.c++输入&输出 4.缺省参数 5.函数重载 前言: 我们在之前学完了c语言的大部分语法知识,是不是意…

论文学习_An Empirical Study of Deep Learning Models for Vulnerability Detection

1. 引言 研究背景:近年来,深度学习漏洞检测工具取得了可喜的成果。最先进的模型报告了 0.9 的 F1 分数,并且优于静态分析器。结果令人兴奋,因为深度学习可能会给软件保障带来革命性的变化。因此,IBM、谷歌和亚马逊等行业公司非常感兴趣,并投入巨资开发此类工具和数据集。…

微信小程序如何实现登陆和注册功能?

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

最新 Kubernetes 集群部署 + Containerd容器运行时 + flannel 网络插件(保姆级教程,最新 K8S 1.28.2 版本)

资源列表 操作系统配置主机名IP所需插件CentOS 7.92C4Gk8s-master192.168.60.143flannel-cni-plugin、flannel、coredns、etcd、kube-apiserver、kube-controller-manager、kube-proxy、 kube-scheduler 、containerd、pause 、crictlCentOS 7.92C4Gk8s-node01192.168.60.144f…

JVM:运行时数据区

文章目录 一、总览二、程序计数器1、介绍2、程序计数器在运行中会出现内存溢出吗? 三、栈1、介绍2、栈帧的组成部分(1)局部变量表(2)操作数栈(3)帧数据(3)栈内存溢出&…

everything搜索不到任何文件-设置

版本: V1.4.1.1024 (x64) 问题:搜索不到任何文件 click:[工具]->[选项]->下图所示 将本地磁盘都选中包含

mavsdk_server安卓平台编译

1.下载好mavsdk并进入mavsdk目录 2.生成docker安卓平台文件 docker run --rm dockcross/android-arm64 >./dockcross-android-arm64 3.生成makefile ./dockcross-android-arm64 cmake -DCMAKE_BUILD_TYPERelease -DBUILD_MAVSDK_SERVERON -DBUILD_SHARED_LIBSOFF -Bbuild/…

【学习笔记】4、组合逻辑电路(下)

接前文《【学习笔记】4、组合逻辑电路(上)》 4.4.5 算术运算电路 1. 半加器和全加器 半加器和全加器是算术运算电路中的基本单元。半加器和全加器是1位相加的组合逻辑电路。 (1)半加器 半加器:只考虑两个加数本身,不考虑低位进…

SuiteCRM SQL注入漏洞复现(CVE-2024-36412)

0x01 产品简介 SuiteCRM是一款屡获殊荣的企业级开源客户关系管理系统,它具有强大的功能和高度的可定制性,且完全免费。 0x02 漏洞概述 SuiteCRM存在SQL注入漏洞,未经身份验证的远程攻击者可以通过该漏洞拼接执行SQL注入语句,从…

C++20中的consteval说明符

在C20中,立即函数(immediate function)是指每次调用该函数都会直接或间接产生编译时常量表达式(constant expression)的函数。这些函数在其返回类型前使用consteval关键字进行声明。 立即函数是constexpr函数,具体情况取决于其要求。与constexpr相同&…

光学遥感图像中的目标检测技术全面综述,以及新的大规模基准数据集DIOR介绍。

原版论文:https://arxiv.org/abs/1909.00133 数据获取地址:https://www.dilitanxianjia.com/15648/ 获取全文可以入下图所示进行操作: 这篇文章主要对光学遥感图像中的目标检测技术进行了全面的综述,并提出了一个新的大规模基准…

神经网络以及简单的神经网络模型实现

神经网络基本概念: 神经元(Neuron): 神经网络的基本单元,接收输入,应用权重并通过激活函数生成输出。 层(Layer): 神经网络由多层神经元组成。常见的层包括输入层、隐藏层…