【MySQL】索引基础

news2024/11/14 17:34:09

文章目录

  • 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.coloradmin.cn/o/1365680.html

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

相关文章

Angular学习第二天--问题记录

一、问题 1.用脚手架搭建完项目之后&#xff0c;缺少app.modules.ts文件&#xff0c; 2.解决办法&#xff1a; 在终端继续输入命令 ng new 项目名称 --no-standalone --routing --ssrfalse 3.完整目录&#xff1a; 二、问题 1.问题来源&#xff0c;源代码&#xff1a; <fo…

K8S API访问控制之RBAC利用

前言 K8S对于API的访问安全提供了访问控制&#xff0c;主要为4个阶段&#xff0c;本文为第二个阶段——鉴权的RBAC。RBAC是基于角色的访问控制&#xff0c;使用kubeadm安装集群1.6版本以上的都默认开启了RBAC。本文主要研究集群可能存在的利用点及相对应的利用手法。 API访问…

kettle的基本介绍和使用

1、 kettle概述 1.1 什么是kettle Kettle是一款开源的ETL工具&#xff0c;纯java编写&#xff0c;可以在Window、Linux、Unix上运行&#xff0c;绿色无需安装&#xff0c;数据抽取高效稳定。 1.2 Kettle核心知识点 1.2.1 Kettle工程存储方式 以XML形式存储以资源库方式存储…

Flutter 图片和资源的高效使用指南

文章目录 指定资源什么是 [pubspec.yaml](https://dart.cn/tools/pub/pubspec) 文件 图片图片常用的配置属性加载本地图片通过 pubspec.yml 文件进行配置图片目录使用 Image.asset 小部件加载本地图片 加载网络图片通过 Image.network小部件加载网络图片&#xff1a;使用Image.…

Idea将xml文件配置为模板

在配置mybatis的mapper映射文件的时候&#xff0c;通常需要到官网拷贝配置文件的内容&#xff0c;这里直接将xml的文件配置为模板&#xff0c;下次可以直接进行创建。

解锁Mac的无限可能:Sensei for Mac - 你的全能系统优化清理助手

你是否经常为Mac的缓慢速度和不断积累的缓存文件而感到烦恼&#xff1f;不用担心&#xff0c;因为今天&#xff0c;我要向您介绍一款全新的系统优化清理工具 - Sensei for Mac。 作为一款卓越的系统清理工具&#xff0c;Sensei for Mac在保持您的Mac系统流畅运行的同时&#x…

1-04C语言执行过程

一、概述 本小节主要讲解一个C程序从源代码到最终执行的过程&#xff0c;这个过程又可以细分为两部分&#xff1a; 源代码到可执行文件的过程可执行文件在内存中执行 本小节是C语言基础当中&#xff0c;比较容易被初学者忽视的知识点。而实际上&#xff1a; 熟悉C程序从源文…

【flink番外篇】9、Flink Table API 支持的操作示例(14)- 时态表的join(java版本)

Flink 系列文章 一、Flink 专栏 Flink 专栏系统介绍某一知识点&#xff0c;并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分&#xff0c;比如术语、架构、编程模型、编程指南、基本的…

模板管理支持批量操作,DataEase开源数据可视化分析平台v2.2.0发布

2024年1月8日&#xff0c;DataEase开源数据可视化分析平台正式发布v2.2.0版本。 这一版本的功能升级包括&#xff1a;在“模板管理”页面中&#xff0c;用户可以通过模板管理的批量操作功能&#xff0c;对已有模板进行快速重新分类、删除等维护操作&#xff1b;数据大屏中&…

Flutter 小技巧之升级适配 Xcode15

美好的 2024 从「适配」开始&#xff0c;按照苹果的尿性&#xff0c;2024 春季开始大家将不得使用 Xcode15 来构建 App &#xff0c;另外根据《2024 的 iOS 的隐私清单》 要求&#xff0c;使用 Flutter 的开发者是无法逃避适配 Xcode15 更新的命运。 另外&#xff0c;众所周知…

NFS 共享存储实验

一、服务器部署 第一步、安装nfs和rpcbind包 [rootserver ~]# yum install -y nfs-utils rpcbind截图&#xff1a; 第二步、这里选择一个 lvm 挂载点做 NFS 共享目录 [rootserver ~]# df -HT截图&#xff1a; 第三步、修改配置文件 [rootserver ~]# vi /etc/exports /home …

【数据库原理】(14)数据控制

数据控制也称为数据保护,包括数据的安全性控制、完整性控制、并发控制和恢复。 数据库的安全性是指保护数据库,防止不合法的使用所造成的数据泄露和破坏。数据库系统中保证数据安全性的主要措施是进行存取控制,即规定不同用户对不同数据对象所允许的执行操作&#xff0c;并规定…

干货|为什么选择独立站?

独立站就像是一个独立的王国&#xff0c;有自己独立的服务器、网站程序和域名。它与依赖平台的模式不同&#xff0c;搭建独立网站可以提供更好的用户体验&#xff0c;建立自己的私域流量&#xff0c;让商家与客户建立更紧密的联系。独立站与第三方平台没有关联&#xff0c;营销…

【控制篇 / 策略】(7.4) ❀ 01. IP地理位置数据库和地理址对象 ❀ FortiGate 防火墙

【简介】在很多使用环境下&#xff0c;我们需要对指定国家的IP地址进行允许或禁止访问操作&#xff0c;例如只允许访问国内IP、禁止访问美国IP等。在早期的配置中&#xff0c;只能手动添加IP地址对象到地址组&#xff0c;繁杂及效率低下&#xff0c;Fortinet提供了基于地理的IP…

oh-my-zsh nvm command not found

如果你在使用 oh-my-zsh 并且在终端输入 nvm 命令时提示 "command not found"&#xff0c;这可能是因为 oh-my-zsh 没有配置 nvm 插件导致的。 a、确保你已经在系统中安装了 nvm。如果没有安装&#xff0c;请参考 nvm 的文档安装。 b、打开 oh-my-zsh 的配置文件&a…

特朗普又搞事情了?这次他把矛头对准了林肯!

美国内战那段血腥历史被他翻了出来&#xff0c;争议四起。2024美国大选之年&#xff0c;两党有力竞选者接连发声&#xff0c;这可真是热闹了。据CNN报道&#xff0c;特朗普在艾奥瓦州举行的竞选集会上说&#xff0c;美国内战“本可以通过谈判”避免&#xff0c;林肯应该采取更多…

通过使用别名让 SQL 更简短-数据库教程shulanxt.com-帆软软件有限公司

MySQL视频教程导航 https://www.shulanxt.com/database/mysqlvideo/p1 SQL 别名 SQL 别名 通过使用 SQL&#xff0c;可以为表名称或列名称指定别名。 基本上&#xff0c;创建别名是为了让列名称的可读性更强。 列的 SQL 别名语法 SELECT column_name AS alias_name FROM …

DevOps搭建(十五)-kubernetes部署项目详细步骤

1、k8s简介 k8s官网地址 https://kubernetes.io/zh-cn/docs/home/ 2、安装kuboard 详细步骤可参考官网 https://kuboard.cn/install/install-k8s.html 2.1、环境准备 至少 2 台 2核4G 的服务器。 选择v1.19&#xff0c;因为高版本的已经把docker给舍弃掉了。 https://k…

selenium如何使用隧道代理请求目标地址?

使用Selenium结合隧道代理IP可以通过以下步骤实现&#xff1a; 获取代理IP&#xff1a; 首先&#xff0c;你需要获得一个可用的隧道代理IP。你可以使用代理服务提供商&#xff08;巨量IP平台提供免费隧道代理测试&#xff09; 安装Selenium&#xff1a; 如果你还没有安装Selen…

redis报错:Creating Server TCP listening socket 127.0.0.1:6379: bind: No error

Redis启动时报错&#xff1a; Creating Server TCP listening socket 127.0.0.1:6379: bind: No error 这个错误说明已经开启了redis&#xff0c;并且已经占用了端口6379&#xff0c;需要停止redis后再开启。 redis-cli.exeshutdownexitredis-server redis.windows.conf 参考…