【MySQL】索引基础

文章目录

  • 1. 索引介绍
  • 2. 创建索引 create index…on…
    • 2.1 explain
    • 2.2 创建索引create index … on…
    • 2.3 删除索引 drop index … on 表名
  • 3. 查看索引 show indexes in …
  • 4. 前缀索引
    • 4.1 确定最佳前缀长度:索引的选择性
  • 5. 全文索引
    • 5.1 创建全文索引 create fulltext index … on…
    • 5.2 全文索引的优点
    • 5.3 全文搜索的两种模式
      • 5.3.1 自然语言模式
      • 5.3.2 布尔模式 in boolean mode
  • 6. 复合索引
    • 6.1 创建复合索引
    • 6.2 复合索引中列的顺序
      • 6.2.1 基本规则
      • 6.2.2 强制使用其他索引进行查询
  • 7. 索引无效
    • 7.1 重写查询以优化查询
    • 7.2 将列单独提出
  • 8. 使用索引排序
  • 9. 覆盖索引
  • 10. 维护索引
    • 10.1 重复索引
    • 10.2 多余索引

1. 索引介绍

  • 索引本质上是数据库引擎用来快速查找数据的数据结构
    • 索引能显著提高查询的性能
    • 索引内部通常被存储为二进制树
    • 在多数情况下,索引很小,足以放进内存,所以使用索引查找数据更快。因为从内存中读取数据总是比从磁盘中读取数据更快。
  • 使用索引会带来的问题
    • 索引会增加数据库的大小,因为索引必须永久存储在表旁。
    • 每次添加、更新或删除记录时,MySQL必须更新对应的索引,这会影响正常操作的性能。
    • 因此,应为性能关键的查询保留索引
  • 不应基于表来创建索引,而是基于查询创建索引。因为使用索引的目的是为了加快运行较慢的查询。

2. 创建索引 create index…on…

2.1 explain

  • 查看MySQL是如何执行语句的:explain

    • type类型:all,全表扫描,读取表中的每一条记录
    • rows行数: 扫描的记录条数
    use sql_store;
    explain select customer_id
    from customers
    where sql_store.customers.state = 'CA'
    

    在这里插入图片描述

2.2 创建索引create index … on…

  • 命名:idx_列名

    create index idx_state on customers(state);
    
  • 创建索引后执行explain:
    在这里插入图片描述

    • type:ref,没有再做全表扫描;
    • rows:行数从1010变为112;
    • possible_keys:可能的键。表中可能会存在多个索引,MySQL为执行这个查询可能会考虑到的索引,MySQL最终挑选性能最佳的索引执行。
    • key:实际使用的索引或键。
  • 练习:查询积分大于1000的顾客

    • 没有创建索引时:type为all,row为1010

      explain select customer_id
      from customers
      where points > 1000;
      

      在这里插入图片描述

    • 为points列创建索引:type为range,rows为529

      create index idx_points on customers(points);explain select customer_idfrom customerswhere points > 1000;
      

      在这里插入图片描述

2.3 删除索引 drop index … on 表名

drop index idx_state on customers;

3. 查看索引 show indexes in …

show indexes in customers;

在这里插入图片描述

  • key_name:索引 / 键名

    • 聚集索引:每张表最多有1个聚集索引。 在表中添加主键, MySQL会自动创建一个索引,可以快速查找记录。
    • 二级索引:创建二级索引时,MySQL会自动将对应的id或主键也纳入二级索引中。例如,积分列上有一个二级索引,但在此索引中,每条记录里都有两个值,为每个顾客的积分和id。
  • collation:排序方式,A为升序,D为降序。

  • cardinality:基数。

    • 表示索引中唯一值的估计数量。此数值是估量,不是真实值。

    • analyze table 表名:生成关于此表的统计信息;执行后再执行查看索引语句即可获取真实值。

      analyze table customers;
      

      在这里插入图片描述

  • index_type:索引类型

    • btree:二进制树
  • 为两张表创建一组关系时,MySQL会自动为外键创建索引,这样就可以快速连接表。

    • 查看orders表的索引,发现外键都有二级索引。

      show indexes in orders;
      

      在这里插入图片描述

4. 前缀索引

  • 使用前缀索引的原因

    • 为字符串列创建索引,如char、varchar、text、blob,索引会占用大量空间,无法达到较好的性能。索引越小越好,可以存在内存中使搜索更快。
    • 索引字符串列时,不想在索引中包含整个列,只想包含列的前几个字符或列前缀,这样能使索引更小。
  • 创建前缀索引:

    • 在创建索引语句中的列名后的括号中输入数字以指定索引包含此列的字符数
    create index idx_lastname on customers(last_name(20))
    
    • char、varchar可不指定括号中的数字;
    • text、blob必须指定括号中的字符数

4.1 确定最佳前缀长度:索引的选择性

  • 索引的选择性指不重复的索引值与数据总量的比值

    select count(*) from customers;
    selectcount(distinct left(last_name, 1))/count(*) as selectivity1,count(distinct left(last_name, 5))/count(*) as selectivity5,count(distinct left(last_name, 10))/count(*)as selectivity10
    from customers;
    

    在这里插入图片描述
    截取前5个字符时由95.6%的数据不同,可以选择前5个字符为前缀创建前缀索引。

  • 索引的选择性在80%以上适合建立,否则不建议建立索引,例如性别等。

5. 全文索引

  • 情景:搜索博客文章。
    • 随着文章数量越来越多,查询会越来越慢。
    • 用like查询,只会返回完全按照单词顺序排列的关键词的文章
    use sql_blog;
    select *
    from posts
    where title like '%react redux%' orbody like '%react redux%';
    
  • 全文索引
    • 包括整个字符串列,而不只是存储前缀
    • 会忽略任何停止词,如in、on、the等

5.1 创建全文索引 create fulltext index … on…

use sql_blog;
create fulltext index idx_title_body on posts(title, body);select *
from posts
where match(title, body) against('react redux');

在这里插入图片描述

  • 查询时,两个内置函数支持全文索引
    • match()函数,要搜索的列
    • against()函数,要搜索的关键词

5.2 全文索引的优点

  • 相关性得分。MySQL会基于若干因素,为包含了要搜索的词的每一行计算相关性得分。
    • 相关性得分:介于0到1的浮点数,0表示没有相关性。
    • 计算相关性得分:在select中写上mathc…against…计算相关性得分。查询结果按照相关性得分降序排序。
      select *,match(title, body) against('react redux') as score
      from posts
      where match(title, body) against('react redux');
      
      在这里插入图片描述

5.3 全文搜索的两种模式

5.3.1 自然语言模式

  • 默认情况的模式。只包含react、只包含redux、包含react和redux,以上三种情况。

    select *,match(title, body) against('react redux') as score
    from posts
    where match(title, body) against('react redux');
    

5.3.2 布尔模式 in boolean mode

  • 可以包括或排除某些单词

  • against(‘text1 -text2 -text3’ in boolean mode)

    • 负号:-text1, 不包括text1
    • 正号:+text1,必须包括text1
    • 双引号:“xuwuuu is a student”,必须包括引号中的短语
  • 例如:

    • 负号:包括react,不包含redux的行

      select *
      from posts
      where match(title, body) against('react -redux' in boolean mode);
      

      在这里插入图片描述

    • 正号:包括react,不包含redux,每一行必须有form

      select *
      from posts
      where match(title, body) against('react -redux +form' in boolean mode);

      在这里插入图片描述

6. 复合索引

  • 场景:搜索位于加州且积分大于1000的顾客

    use sql_store;
    show indexes in customers;
    explain select customer_id
    from customers
    where state = 'CA' and points > 1000;
    

    在这里插入图片描述

    • 先把搜索范围缩小到位于加州的顾客。按照state索引进行搜索,找到位于‘CA’的所有数据。
    • 然后扫描所有位于加州的顾客,并查看积分。此时的查询需要表扫描,因为state索引中没有顾客的积分。但如果加州有1000万顾客,查询还是会很慢。

6.1 创建复合索引

  • 允许对多列建立索引,可优化查询。

  • 可以在state列和points列上创建复合索引,可以快速找到位于任何州、拥有任意积分的数据

    use sql_store;
    create index idx_state_points on customers(state, points);
    explain select customer_id
    from customers
    where state = 'CA' and points > 1000;
    

    在这里插入图片描述
    此时的查询需要扫描58行,之前需要扫描112行。

    可能的键:有3个,state上、points上、state和points上的复合索引,复合索引在优化查询上更好,因此最后选择了复合索引进行查询

  • 一个索引中最多可包含16列,一般在4-6列能达到很好的性能,但最终应根据实际查询和数据量进行确定。

6.2 复合索引中列的顺序

6.2.1 基本规则

  • 应该对列进行排序,让更频繁使用的列排在最前面
    • 如有5个查询,大多数或全部的查询都按state查找顾客,把state放在最前面就很合理,这有助于缩小搜索范围
  • 基数更高的列排在最前面
    • 基数表示索引中唯一值的数量
    • 基数更高的列排在前面能把搜索范围缩小到更少的数量
  • 只是基本规则,而不是硬性规则。还应充分考虑实际的查询和数据

6.2.2 强制使用其他索引进行查询

  • 在from和where中间使用use index(索引名称)

    explain select customer_id
    from customers
    use index(idx_lastname_state)
    where state = 'NY' and last_name like 'A%';
    

7. 索引无效

有些情况下,即使有索引,但仍会遇到性能问题

  • or 进行条件查询:

    • type类型为index,是全索引扫描。
    • 全索引扫描比表扫描快,因为它不涉及从磁盘读取每个记录
    • rows为1010。但还是需要扫描1010条记录。
    explain select customer_id
    from customers
    where state = 'CA' or points > 1000;
    

    在这里插入图片描述

7.1 重写查询以优化查询

  • 优化上述查询:
    • 重写查询,以尽可能最好的方式利用索引。把查询拆分成两段更小的查询。

    • 选择所有位于加州的顾客,和另一个选择了超过1000积分的数据进行联合查询。

    • 但第二段points查询,在idx_state_points索引上位于第二列,查询效率也不高。因此要在points列上创建单独的索引。

    • 两端查询rows为112+529,比1010少了很多。

      create index idx_points on customers(points);
      explainselect customer_id from customerswhere state = 'CA'unionselect customer_id from customerswhere points > 1000;
      

      在这里插入图片描述

7.2 将列单独提出

  • 想要利用索引,需要单独把列提出来

    • 以下两段查询使用的索引不同
    • 第一段使用的是index全索引扫描;第二段是range范围扫描。
    explain select customer_id from customers
    where points - 10 > 2010;explain select customer_id from customers
    where points > 2000;
    

    在这里插入图片描述

    在这里插入图片描述

8. 使用索引排序

  • 例子,按顾客所在的州对其进行排序

    -- 按使用了索引的列进行排序
    explain select customer_id from customers
    order by state;-- 按没有使用索引的列进行排序
    explain select customer_id from customersorder by first_name;
    

    结果:第一个type是index,按照state在前的索引进行排序。第二个type为all,进行全表扫描,使用外部排序。
    在这里插入图片描述

    在这里插入图片描述

  • 基本规则

    • order by子句中的列的顺序,应该与索引中列的顺序相同
    • 基于两列的复合索引,如A列和B列,可以按A排序按A和B排序按A降序和B降序排序。但不能改变顺序,也不能在A和B中间添加一列

9. 覆盖索引

  • 覆盖索引:一个包含所有满足查询所需要的数据的索引。通过此索引,MySQL可以在不读取表的情况下就执行查询。
    • 先查看where子句,看最常用的列,将其包含在索引中;
    • 看order by子句中的列,看是否在索引中能包含这些列;
    • 最后看select子句中使用的列,如果也包含了这些列,就会得到一个覆盖索引。
    • 得到覆盖索引后,MySQL就可以用索引满足查询。
  • 例子:当选择 * 时,使用的是全表扫描
    • 在state_points上的复合索引包含了3列,id列、state列和points列。MySQL会自动把主键包括在二级索引中。
    explain select * from customersorder by state;
    
    在这里插入图片描述

10. 维护索引

  • 在创建新索引之前检查现有索引,避免创建重复索引和多余索引。
  • 确保删除重复索引、多余索引和未使用的索引。

10.1 重复索引

  • 同一组的列且顺序一致的索引,如ABC和ABC

10.2 多余索引

  • 在A和B两列上有一个复合索引,再在A上创建另外一个索引,这就会被判定为多余索引。因为原来的索引也可以优化包含列A的查询。
  • 在A和B两列上有复合索引的情况下,创建B和A的复合索引或单独创建B的索引是可以的。

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

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

相关文章

Vue3.4更新 “Slam Dunk“发布!!!

Announcing Vue 3.4 | The Vue Point. vue3.4更新官方文档 在vue2即将结束更新的时候,vue3迎来了一个重要的更新。代号为“🏀 Slam Dunk”,即"灌篮高手"。这个版本进行了很多显著的内部改进,最重要的是模版解析的底层逻…

Github 2024-01-08开源项目周报 Top14

根据Github Trendings的统计,本周(2024-01-08统计)共有14个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5TypeScript项目3C项目2Dart项目1QML项目1Go项目1Shell项目1Rust项目1JavaScript项目1C#项目1 免费…

IO进程线程Day5

1> 将互斥机制代码重新实现一遍 #include<myhead.h>char buf[128]; //临界资源pthread_mutex_t mutex; //创建锁资源//分支线程 void* task(void* arg) {while(1){//获取锁资源pthread_mutex_lock(&mutex);printf("这里是分支线程:%s\n",buf);st…

多线程模板应用实现(实践学习笔记)

出处&#xff1a;B站码出名企路 个人笔记&#xff1a;因为是跟着b站的教学视频以及文档初步学习&#xff0c;可能存在诸多的理解有误&#xff0c;对大家仅供借鉴&#xff0c;参考&#xff0c;然后是B站up阳哥的视频&#xff0c;我是跟着他学。大家有兴趣的可以到b站搜索。加油…

CAD安装教程

CAD安装教程 目录 一&#xff0e; 下载CAD二&#xff0e; 安装CAD 一&#xff0e; 下载CAD 如果需要CAD安装包请私信。 二&#xff0e; 安装CAD 解压压缩包AutoCAD2022中文版&#xff0c;以管理员身份运行AutoCAD_2022_Simplified_Chinese_Win_64bit_dlm.sfx。 选择解压路径。…

【sklearn练习】datasets的使用

一、数据集分类 1、fetch类的数据集&#xff1a; 以 "fetch" 开头的数据集&#xff0c;这些数据集通常不包含在 scikit-learn 的标准安装中&#xff0c;需要从远程服务器上下载。这些数据集通常比标准数据集更大&#xff0c;因此在使用它们之前&#xff0c;需要通过…

Spring MVC中@ExceptionHandler注解的智能处理机制——无需显示指定异常类型

概述 在深入探讨Spring MVC框架时&#xff0c;我们经常会遇到异常处理的相关场景。其中&#xff0c;ExceptionHandler注解是一个非常重要的工具&#xff0c;它允许我们声明一个方法来专门处理特定类型的异常。有趣的是&#xff0c;Spring容器具备智能化的异常类型关联功能&…

自动驾驶:低阶可部署的单目测距算法-基于YOLO与透视变换

一、开发环境 部署平台&#xff1a;英伟达的Jetson Nano 环境&#xff1a;Linux ROS 语言&#xff1a;C 设备&#xff1a;1920*1080像素的摄像头、开发板。 模型&#xff1a;yolo-v8s 二、单目测距实现思路 0、标定相机和车辆&#xff08;假设已经标定完成&#xff09; 1、通…

06-微服务-SpringAMQP

SpringAMQP SpringAMQP是基于RabbitMQ封装的一套模板&#xff0c;并且还利用SpringBoot对其实现了自动装配&#xff0c;使用起来非常方便。 SpringAmqp的官方地址&#xff1a;https://spring.io/projects/spring-amqp SpringAMQP提供了三个功能&#xff1a; 自动声明队列、交…

[论文阅读] Revisiting Feature Propagation and Aggregation in Polyp Segmentation

[论文地址] [代码] [MICCAI 23] Abstract 息肉的准确分割是筛查过程中有效诊断结直肠癌的关键步骤。 由于能够有效捕获多尺度上下文信息&#xff0c;普遍采用类似UNet 的编码器-解码器框架。 然而&#xff0c;两个主要限制阻碍了网络实现有效的特征传播和聚合。 首先&#xff…

基于SSM的企业员工管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

[AutoSar]基础部分 RTE 04 数据类型的定义及使用

目录 关键词平台说明一、数据类型分类二、Adt三、Idt四、Base 数据类型五、units六、compu methods七、data constraint 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、数据…

python自动化测试面试题与答案汇总

对于机器学习算法工程师而言,Python是不可或缺的语言,它的优美与简洁令人无法自拔,下面这篇文章主要给大家介绍了关于30道python自动化测试面试题与答案汇总的相关资料,需要的朋友可以参考下 1、什么项目适合做自动化测试&#xff1f; 关键字&#xff1a;不变的、重复的、规范…

ts axios 指定返回值类型,返回数据类型不确定该怎么办 typescript

ts axios 指定返回值类型&#xff0c;返回数据类型不确定该怎么办 typescript 转到 ts 以来&#xff0c;一直有个问题困扰着我&#xff0c;就是每次用 axios 获取数据时&#xff0c;返回值 res 的类型都不能确定&#xff0c;这就导致编辑器一直提示我&#xff1a; 原因 原因是…

SPON世邦 IP网络对讲广播系统 多处文件上传漏洞复现

0x01 产品简介 SPON世邦IP网络对讲广播系统是一种先进的通信解决方案,旨在提供高效的网络对讲和广播功能。 0x02 漏洞概述 SPON世邦IP网络对讲广播系统 addscenedata.php、uploadjson.php、my_parser.php等接口处存在任意文件上传漏洞,未经身份验证的攻击者可利用此漏洞上…

Mac M1 Parallels CentOS7.9 Deploy Docker + Rancher + K8S(HA+More Master)

一、准备虚拟机资源 虚拟机清单 机器名称IP地址角色rancher10.211.55.200管理K8S集群k8svip10.211.55.199K8S VIPmaster0110.211.55.201K8S集群主节点master0210.211.55.202K8S集群主节点master0310.211.55.203K8S集群主节点node0110.211.55.211K8S集群从节点node0210.211.55…

Vue 自定义仿word表单下拉框组件,让操作更符合用户习惯

预览时显示界面 进入编辑框时 组件代码 <template><div class "paper-select ui-select flex flex-col full-width" ><div ref"content" class"content font-s flex flex-center-cz padding-left-m padding-right-m flex-space-be…

C++入门教程,C++基础教程(第一部分:从C到C++)七

由C语言发展而来的一种面向对象的编程语言。 第一部分、从C语言到C 本章讲述 C 语言的简史&#xff0c;以及 C 语言中与面向对象关系不大、C语言中没有的特性。这些特性能够增加编程的便利性&#xff0c;提高程序的可扩充性。 十三、如何规范地使用C内联函数 inline 关键字…

Mac M1 Parallels CentOS7.9 Install Parallels Tools

一、挂载parallels-tools安装包 mkdir /media/cdrom/ mount /dev/cdrom /media/cdrom/ mount: /dev/sr0 写保护&#xff0c;将以只读方式挂载二、GCC升级 yum install -y centos-release-scl yum install -y devtoolset-8-gcc*# 切换当前会话中gcc版本为8 scl enable devtool…

TypeScript 从入门到进阶之基础篇(八)函数篇

系列文章目录 TypeScript 从入门到进阶系列 TypeScript 从入门到进阶之基础篇(一) ts基础类型篇TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇TypeScript 从入门到进阶之基础篇(三) 元组类型篇TypeScript 从入门到进阶之基础篇(四) symbol类型篇TypeScript 从入门到进阶…