【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_id
      		        from customers
      		        where 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;
    select
        count(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%' or
          body 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);
      explain
          select customer_id from customers
          where state = 'CA'
          union
          select customer_id from customers
          where 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 customers
            order 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 customers
            order by state;
    
    在这里插入图片描述

10. 维护索引

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

10.1 重复索引

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

10.2 多余索引

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

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

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

相关文章

dnSpy调试Web应用程序

文章目录 前言一、dnSpy是什么?二、如何使用dnSpy三、如何调试Web应用程序四、下载总结 前言 dnSpy是一个.NET程序集调试器和编辑器,主要用于调试和编辑没有源码的.NET程序集。 一、dnSpy是什么? dnSpy是一个.NET程序集调试器和编辑器&#…

静态网页设计——极乐迪斯科(HTML+CSS+JavaScript)

前言 声明:该文章只是做技术分享,若侵权请联系我删除。!! 感谢大佬的视频: https://www.bilibili.com/video/BV11k4y1X7mH/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术:HTMLCSSJS(…

SpringCloud系列篇:核心组件之配置中心组件

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.前言 二.配置中心组件是什么 三…

揭秘六大热门认证考试

六大热门认证考试是什么❓今天为大家详细解读PMP、ACP、CDGA、软考中项、软考高项、NPDP、CISP等热门认证考试,让你不再彷徨👇 1️⃣PMP 👑PMP认证是全qiu公ren的项目管理专业认证,旨在评估项目管理人员在项目过程中所需的知识、技…

重生奇迹MU游戏中勇者大陆

玩重生奇迹MU,我们进入游戏首先会来到勇者大陆。在看到勇者大陆市场,有很多交易的玩家也在这里,在勇者市场里面有商店。接下来介绍主要的NPC 的作用和怪物有那些? 勇者大陆卖药的商店老板莉雅 商店里面会有卖治疗药水&#xff0…

06-微服务-SpringAMQP

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

红队打靶练习:EVM: 1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto 5、whatweb 目录探测 1、gobuster 2、dirsearch WEB wpscan get username get password MSF get shell 提权 get root get flag 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interf…

NACHI机器人模拟示教器如何切换中文

前言 现在开始学习机器人的编程语言,那么要学习会用首先得用模拟示教器来学习,但是全是英文确实比较难受一些些,没有中文来的直观。所以摸透一下如何给示教器更换语言。 具体步骤 步骤一:将中文的汉化包下载下来。具体的下载链…

STL——string详解

目录 💡介绍 💡string的基本操作 💡string的构造函数 💡string赋值操作 💡string字符串拼接 💡string的查找和替换 💡string字符串比较 💡string字符存取 💡str…

爬虫实战 - 微博评论数据可视化

简介: 我们都知道在数据比较少的情况下,我们是可以很轻易的获取到数据中的信息。但是当数据比较庞大的时候呢,我们就很难看出来了。尤其是面对现如今数以万计的数据,就更了。 不过好在我们可以通过计算机来帮我们进行分析&#…

算力-计算量,关于TOPS和FLOPS,及FLOPs

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/zaibeijixing/article/details/135425642 ———————————————— 目录 一、易混淆的三…

知识图谱之汽车实战案例综述与前瞻分析

知识图谱的前置介绍 什么是知识图谱 知识图谱本质(Knowledge Graph)上是一种叫做语义网络(semantic network ) 的知识库,即具有有向图结构的一个知识库;图的结点代表实体(entity)或者概念(con…

学习笔记——C++一维数组

1,一维数组的定义方式 三种定义方式 1,数据类型 数组名[ 数组长度 ]; 2,数据类型 数组名[ 数组长度 ]{值1,值2,值3 ……};//未说明的元素用0填补 3,数据类型 数组名[ ]{值1&…

【Project】TPC-Online Module (manuscript_2024-01-07)

PRD正文 一、概述 本模块实现隧道点云数据的线上汇总和可视化。用户可以通过注册和登录功能进行身份验证,然后上传原始隧道点云数据和经过处理的数据到后台服务器。该模块提供数据查询、筛选和可视化等操作,同时支持对指定里程的分段显示和点云颜色更改…

WEB 3D技术 three.js 元素居中与获取元素中心点

本文 我们来说让物体居中 以及获取它的中心点 我们上文留下的这个代码 import ./style.css import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import { RGBELoader } from "three/e…

LCD—液晶显示

本节主要介绍以下内容 显示器简介 液晶控制原理 秉火3.2寸液晶屏简介 使用FSMC模拟8080时序 NOR FLASH时序结构体 FSMC初始化结构体 一、显示器简介 显示器属于计算机的I/O设备,即输入输出设备。它是一种将特定电子信息输出到屏幕上再反射到人眼的显示工具。…

【Java集合篇】HashMap 是如何扩容的

HashMap 是如何扩容的 ✔️ 为什么需要扩容?✔️ 桶元素重新映射✔️链表重新链接✔️ 取消树化✔️拓展知识仓✔️除了rehash之外,哪些操作也会将树会退化成链表? ✔️ 为什么需要扩容? HashMap在Java等编程语言中被广泛使用,用于存储键值对数据。Ha…

【51单片机】独立按键控制LED灯

不同于上篇文章只用代码控制,这次我们要再加上独立按键一同控制LED灯 目录 独立按键控制LED亮灭:代码实现: 独立按键控制LED状态:代码实现: 独立按键实现二进制LED显示:代码实现: 独立按键控制…

Linux进程之间的通信机制(IPC)概述

Linux进程之间通信 为什么需要进程间通信? 进程间的通信(IPC)指的是两个任意的进程之间的通信。 同一进程在一个地址空间中,所以同一进程的不同模块,(不同函数,不同文件)之间都是很…

【软件测试】黑盒测试

《等价类划分法》 有效等价类无效等价类 &#xff08;输入条件&#xff09;10 < x < 100&#xff08;有效等价类&#xff09;10 < x < 100&#xff08;无效等价类&#xff09;x < 10 和 x >100 《边界值分析法》 基本原则 如果输入条件规定了取值范围&…
最新文章