秋招突击——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语句
  • 主键索引最好是单调递增的值
    • 主键是随机的值,插入会引起页分裂现象,导致大量的内存碎片
  • 对于大的字符串索引,考虑使用前缀索引只对前缀部分简历索引,节省索引的存储空间。

总结

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

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

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

相关文章

映美精黑白相机IFrameQueueBuffer转halcon的HObject

映美精黑白相机&#xff0c;用wpfhalcon开发取图 1.到官网下载&#xff0c;开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…

CentOS7二进制安装和YUM安装mongodb,服务器无法安装5.0以上的 mongodb 数据库报错 Illegal instruction

文章目录 MongoDB 安装二进制安装YUM 安装 Tips:1、MongoDB安装问题2、MongoDB登录3、MongoDB排序时内存大小限制和创建索引4、创建用户5、Java yaml使用密码连接mongodb6、MongoDB增删改查 MongoDB 安装 二进制安装 [rootmysql5-7 mongodb-6.0.4]# cat start.sh #!/bin/bash…

小程序-设置环境变量

在实际开发中&#xff0c;不同的开发环境&#xff0c;调用的接口地址是不一样的 例如&#xff1a;开发环境需要调用开发版的接口地址&#xff0c;生产环境需要正式版的接口地址 这时候&#xff0c;我们就可以使用小程序提供了 wx.getAccountInfoSync() 接口&#xff0c;用来获取…

作为空降高管,如何服众?教你3个步骤,站稳脚跟

作为空降高管&#xff0c;如何服众&#xff1f;教你3个步骤&#xff0c;站稳脚跟 第一招&#xff1a;请“尚方宝剑” 空降领导最大的劣势有4点&#xff1a; ①、缺乏支持&#xff0c;没有群众基础&#xff0c;不得民心。 ②、对环境不熟悉&#xff0c;不了解团队结构。 ③…

TCP传输控制协议二

TCP 是 TCP/IP 模型中的传输层一个最核心的协议&#xff0c;不仅如此&#xff0c;在整个 4 层模型中&#xff0c;它都是核心的协议&#xff0c;要不然模型怎么会叫做 TCP/IP 模型呢。 它向下使用网络层的 IP 协议&#xff0c;向上为 FTP、SMTP、POP3、SSH、Telnet、HTTP 等应用…

12-《向日葵》

向日葵 向日葵&#xff08;拉丁文&#xff1a;Helianthus annuusL.&#xff09;&#xff0c;为木兰纲、菊目、菊科、向日葵属的一年生草本植物。高1&#xff5e;3.5米。茎直立&#xff0c;圆形多棱角&#xff0c;质硬被白色粗硬毛。广卵形的叶片通常互生&#xff0c;先端锐突或…

如何在项目中打印sql和执行的时间

目标&#xff1a;打印DAO方法中sql和执行的时间 一种方式是去实现Mybatis的拦截器Interceptor &#xff0c;比较麻烦&#xff1b; 这里介绍一种比较简单的实现方式&#xff1b; 1、如何打印sql&#xff1f; 配置文件加这个可以打印出com.zhenhui.ids.busi.watch包下执行的sq…

Nacos服务公网环境登陆报密码错误问题排查

作者&#xff1a;小丫 一、问题现象 nacos服务内网可以正常登录&#xff0c;如下&#xff1a; 走公网代理出来之后&#xff0c;无法正常登录&#xff0c;报错"用户名密码错误" 二、排查步骤 1、链路分析 首先确认公网代理的链路&#xff1a; 域名—>haprox…

Stable Diffusion 深度探索:从入门到精通的全方位教程

在人工智能艺术创作的浪潮中&#xff0c;Stable Diffusion 作为一股不可忽视的力量&#xff0c;正以其独特的魅力吸引着无数创作者和科技爱好者的目光。本文旨在为大家提供一份详尽的 Stable Diffusion 教程&#xff0c;从基础概念到高级应用&#xff0c;带领你一步步走进这个充…

Detrs beat yolos on real-time object detection

Abstract 然而&#xff0c;我们观察到nnms对yolo的速度和准确性产生了负面影响。最近&#xff0c;端到端基于变压器的检测器(DETRs)为消除NMS提供了一种替代方案。然而&#xff0c;高昂的计算成本限制了它们的实用性&#xff0c;阻碍了它们充分发挥排除NMS的优势。在本文中&am…

【WebGIS】从设计层面设计系统

本项目在通过现代信息技术手段&#xff0c;对古村古镇进行多方位、多角度的数字化记录、展示与传播&#xff0c;实现文化遗产的数字化保护、活化利用与共享。项目内容主要包括&#xff1a;1&#xff09;古村古镇数据库的建立&#xff1a;通过多种渠道收集古村古镇的各类信息&am…

【第32章】MyBatis-Plus之代码生成器配置

文章目录 前言一、概述1.特点说明2.示例配置3. 数据库配置 (DataSourceConfig) 二、全局配置 (GlobalConfig)1.方法说明2.示例配置 三、包配置 (PackageConfig)1. 方法说明2. 示例配置 四、模板配置 (TemplateConfig)1. 方法说明2. 示例配置 五、注入配置 (InjectionConfig)1. …

近期matlab学习笔记,学习是一个记录,反复的过程

近期matlab学习笔记&#xff0c;学习是一个记录&#xff0c;反复的过程 matlab的mlx文件在运行的时候&#xff0c;不需要在文件夹路径下&#xff0c;也能运行&#xff0c;但是需要调用子函数时&#xff0c;就需要在文件所在路径下运行 那就先运行子函数&#xff0c;把路径换过来…

2019-2023年全球固定宽带和移动(蜂窝)网络性能(更新)

简介 全球固定宽带和移动&#xff08;蜂窝&#xff09;网络性能&#xff0c;分配给缩放级别 16 的网络 mercator 瓷砖&#xff08;赤道处约 610.8 米乘 610.8 米&#xff09;。数据以 Shapefile 格式和 Apache Parquet 格式提供&#xff0c;几何图形以 EPSG:4326 中的已知文本…

jmeter-beanshell学习8-for循环

一个稍微有点难度的东西 要把响应结果的所有名字都取出来&#xff0c;然后怎么处理看自己需求。比如找某个人是不是在这里&#xff0c;或者把所有人都写进一个文档&#xff0c;我就不编场景了 第一步想要取出所有名字&#xff0c;还得靠万能的正则表达式提取器&#xff0c;jso…

JDK安装详细教程(以JDK17为例)

一、JDK的下载 1. 前往oracle官网下载JDK Java Archive Downloads - Java SE 17 在这里选择对应的JDK版本&#xff0c;我这里就直接选择JDK17的版本了。 然后下载对应的软件包&#xff0c;我这里采用的是Windows的安装程序。 点击上述圈起来的链接即可下载安装包&#xff0c;…

GloVe: Global Vectors for Word Representation论文笔记解读

基本信息 作者Jeffrey Penningtondoi10.3115/v1/D14-1162发表时间2014期刊EMNLP网址https://aclanthology.org/D14-1162.pdf 研究背景 1. What’s known 既往研究已证实 全局矩阵分解方法&#xff1a;LSA&#xff0c;考虑整个语料库词频的统计信息得到共现矩阵&#xff0c;通…

vue实现a-model弹窗拖拽移动

通过自定义拖拽指令实现 实现效果 拖动顶部&#xff0c;可对整个弹窗实施拖拽&#xff08;如果需要拖动底部、中间内容实现拖拽&#xff0c;把下面的ant-modal-header对应改掉就行&#xff09; 代码实现 编写自定义指令 新建一个ts / js文件&#xff0c;用ts举例 import V…

计算机视觉之SSD目标检测

模型简介 SSD是一种单阶段目标检测算法&#xff0c;通过卷积神经网络进行特征提取&#xff0c;并在不同的特征层进行检测输出&#xff0c;实现多尺度检测。它采用了anchor的策略&#xff0c;预设不同长宽比例的anchor&#xff0c;并在每个输出特征层上预测多个检测框。SSD框架…

7 月12日学习打卡--栈和队列的相互转换

hello大家好呀&#xff0c;本博客目的在于记录暑假学习打卡&#xff0c;后续会整理成一个专栏&#xff0c;主要打算在暑假学习完数据结构&#xff0c;因此会发一些相关的数据结构实现的博客和一些刷的题&#xff0c;个人学习使用&#xff0c;也希望大家多多支持&#xff0c;有不…