MySQL优化(二):索引的类型、匹配原则、创建原则

目录

    • 索引的优缺点
    • 索引类型
      • 聚簇索引(主键索引)
      • 非聚簇索引(二级索引、辅助索引)
    • 索引匹配的原则
      • 最左匹配原则
    • 无法使用索引的场景
    • 索引创建的原则
    • 使不使用索引的依据到底是什么?
    • 参考

索引的优缺点

常见的索引结构有: B 树, B+树和 Hash。

  • 优点:加快数据的检索速度
  • 缺点:
    1. 创建索引和维护索引需要耗费许多时间:当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
    2. 占用物理存储空间 :索引需要使用物理文件存储,也会耗费一定空间。

索引类型

聚簇索引(主键索引)

聚簇索引即索引结构和数据一起存放的索引,结构为B+树。
InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。

聚簇索引结构如下:

在这里插入图片描述

非聚簇索引(二级索引、辅助索引)

在聚簇索引之上创建的索引称之为辅助索引(二次索引),辅助索引节点只包含索引列值和主键值,因此辅助索引访问数据总是需要二次查找(即:通过二次索引找到主键值后回到聚簇索引找到对应的数据行)。
辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的Page Directory找到数据行。
Innodb辅助索引非叶子节点只有索引列(不含主键),叶子节点并不包含行记录的全部数据,叶子节点只包含索引列和相应行数据的聚簇索引键。

Innodb二级索引,索引列值全相同的情况下,节点按主键值排序。

二级索引结构如下:
在这里插入图片描述

索引匹配的原则

最左匹配原则

如果创建一个联合索引, 此索引的任何前缀都会用于查询, 例如:
(col1, col2, col3)这个联合索引的所有前缀就是(col1), (col1, col2), (col1, col2, col3), 包含这些列的查询都会启用索引查询.
其他所有不在最左前缀里的列都不会启用索引, 即使包含了联合索引里的部分列也不会使用索引. 即上述中的(col2), (col3), (col2, col3) 都不会启用索引去查询.
注意:(col1, col3)会启用(col1)的索引查询。

无法使用索引的场景

  1. 复合索引的情况下,查询条件不满足索引最左的原则
  2. Mysql估计使用索引比全表扫描慢
  3. 索引 不能是表达式(函数)的一部分
    只有独立的列能使用索引,如:SELECT * FROM table WHERE id -1 = 1000; 无法使用索引 因为索引 id-1 不为独立的列
  4. 负向查询(not , not in, not like, <>, != ,!>,!< ) 不会使用索引
  5. 以%开头的LIKE查询不能够利用B-tree索引
  6. 用or分割开的条件,or前条件有索引,or后的列没有索引

    因为or后面的条件没有索引,那么后面的查询肯定要进行全表扫描,在存在全表扫描的情况下,就没有必要多一次索引扫描增加IO访问。

索引创建的原则

  • 不要使用更新频繁的列作为主键,不适用多列主键(相当于联合索引)
  • 不要使用 UUID,MD5,HASH,字符串列作为主键(无法保证数据的顺序增长),容易导致页分裂及随机IO,影响插入的速度。推荐使用自增值作为主键。
  • 索引列的顺序:
    1. 区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数)
    2. 尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO 性能也就越好)
    3. 使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)
  • 避免建立冗余索引和重复索引(增加了查询优化器生成执行计划的时间)
    冗余索引示例:index(a,b,c)、index(a,b)、index(a)
  • 对于频繁的查询优先考虑使用覆盖索引

覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引
覆盖索引的好处:
避免 Innodb 表进行索引的二次查询: Innodb 是以聚集索引的顺序来存储的,对于 Innodb 来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据的话,在查找到相应的键值后,还要通过主键进行二次查询才能获取我们真实所需要的数据。而在覆盖索引中,二级索引的键值中可以获取所有的数据,避免了对主键的二次查询 ,减少了 IO 操作,提升了查询效率。
可以把随机 IO 变成顺序 IO 加快查询效率: 由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围查找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序 IO。

使不使用索引的依据到底是什么?

在满足了使用索引的条件下,是否使用索引取决于使用索引的成本。

此段摘抄自:MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

MySQL中决定使不使用某个索引执行查询的依据很简单:就是成本够不够小。而不是是否在WHERE子句中用了IS NULL、IS NOT NULL、!=这些条件。

答案很简单:成本。对于使用二级索引进行查询来说,成本组成主要有两个方面:
1. 读取二级索引记录的成本
2. 将二级索引记录执行回表操作,也就是到聚簇索引中找到完整的用户记录的操作所付出的成本。

查询列不在二级索引时,要扫描的二级索引记录条数越多,那么需要执行的回表操作的次数也就越多,达到了某个比例时,使用二级索引执行查询的成本也就超过了全表扫描的成本(举一个极端的例子,比方说要扫描的全部的二级索引记录,那就要对每条记录执行一遍回表操作,自然不如直接扫描聚簇索引来的快)。

参考

  • 什么是索引?
  • 官方文档解释MySQL最左匹配(最左前缀)原则
  • MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!
  • MySQL优化指南
  • mysql 存在索引但不能使用索引的典型场景
  • 聚簇索引和非聚簇索引(通俗易懂 言简意赅)

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

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

相关文章

jedis对redis键加锁+解锁+事务提交

【README】 redis的java客户端对键加锁和解锁&#xff08;Jedis.watch() Jedis.unwatch() &#xff09;&#xff1b; 【1】代码 /*** redis加锁-watch * 【场景描述】&#xff1a; watch命令就是标记一个键&#xff0c;如果标记了一个键&#xff0c;* 在提交事务前如果该键…

win10关闭快速启动_装系统不求人,快速制作启动U盘,傻瓜式重装WIN10

在以前如果我们的电脑系统损坏&#xff0c;无法进入WINDOWS系统&#xff0c;在需要重装WINDOWS系统时&#xff0c;一般的做法是&#xff0c;下载一个WINDOWS系统镜像&#xff0c;制作一个PE启动盘&#xff0c;在PE里安装系统镜像。这样传统的WINDOWS系统重装过程麻烦且耗时。而…

漫画:什么是SnowFlake算法

转载自 漫画&#xff1a;什么是SnowFlake算法方法一&#xff1a;UUIDUUID是通用唯一识别码 (Universally Unique Identifier)&#xff0c;在其他语言中也叫GUID&#xff0c;可以生成一个长度32位的全局唯一识别码。String uuid UUID.randomUUID().toString()结果示例&#xff…

FeignClient调用服务及上传文件的注意点及问题

目录代码示例文件服务接口调用方注意点&#xff1a;2021.3.16更新&#xff1a;发新的坑坑点&#xff1a;原因分析部分异常及解决方案异常一&#xff1a;[Method has too many Body parameters](https://blog.csdn.net/haishiyizhenfeng/article/details/80607003)异常二&#x…

redis主从复制部署策略+jedis设置主从

【README】 redis 有3种集群模式&#xff0c;包括 主从&#xff0c; 哨兵&#xff0c; cluster&#xff1b; 本文主要po出 主从&#xff1b; master 192.168.163.201 6382 slave 192.168.163.202:6382 【1】从机 202:6382 的 redis.conf 配置 只需要编写 slaveof 192.…

python绘图时的分解问题的步骤-零基础学python-15.2 分解函数

这一章节我们来说说函数的一些主要概念 我们以一小段代码为例&#xff1a; >>> def test(): pass >>> 1. def是可执行的代码 >>> test() >>> 我们调用test方法&#xff0c;尽管什么都没有&#xff0c;但是test已经执行了 2.def创建了一个对…

千万条数据,Stack Overflow是如何实现快速分页的

转载自 千万条数据&#xff0c;Stack Overflow是如何实现快速分页的 Stack Overflow 在分页机制中使用页码代替偏移量&#xff0c;页码指向基于 LIMIT 和 OFFSET 的查询。假设要对 1000 万条记录进行分页&#xff0c;跳到最后一页会非常慢&#xff0c;但 Stack Overflow 还是想…

ubuntu系统下安装docker并部署Springboot+mysql+redis

目录安装DockerDocker常用命令构建mysql容器构建Redis容器构建Springboot应用镜像及容器&#xff08;1&#xff09;springboot使用maven将程序打成jar包&#xff0c;接着编写Dokerfile文件&#xff0c;[Dockerfile详细介绍](http://www.dockerinfo.net/dockerfile%e4%bb%8b%e7%…

redis连接池

【README】 本文旨在po出 redis连接池的测试用例 <dependencies><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.5.1</version></dependency></dependencies> 【1】 代…

qmc0转换mp3工具_GoldenRecords for Mac(唱片录音转换软件)

想要将你最喜欢的唱片音乐转换成为方便易于携带的数字音频么&#xff1f;GoldenRecords Mac版是一款Macos上的唱片录音转换软件&#xff0c;用户可以将自己收藏的旧唱片快速转换成为自己喜欢的数字音频音乐&#xff0c;随时随地想听就听&#xff01;GoldenRecords mac版&#x…

java提高篇之抽象类与接口

转载自 java提高篇之抽象类与接口 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。 抽象类与接口是java语言中对抽象概念进行定义的两种机制&#xff0c;正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似&…

Java中synchronized同步块的执行流程

必要知识 Java 对象的数据结构 在 HotSpot 虚拟机中&#xff0c;Java 对象在内存中存储的布局可以分为 3 块区域&#xff1a;对象头&#xff08;Header&#xff09;、实例数据&#xff08;Instance Data&#xff09;和对齐填充&#xff08;Padding&#xff09;对象头中的 Mar…

深入理解Java的接口和抽象类

转载自 深入理解Java的接口和抽象类 对于面向对象编程来说&#xff0c;抽象是它的一大特征之一。在Java中&#xff0c;可以通过两种形式来体现OOP的抽象&#xff1a;接口和抽象类。这两者有太多相似的地方&#xff0c;又有太多不同的地方。很多人在初学的时候会以为它们可以随意…

转: 记录centos7 安装erlang22.3和rabbitMQ

转&#xff1a; https://blog.csdn.net/weixin_44436611/article/details/109492936 记录centos7 安装erlang22.3和rabbitMQ 记录centos7 安装erlang22.3和rabbitMQTOC 官网地址&#xff1a;https://www.rabbitmq.com/install-rpm.html#install-erlang 部分rpm包&#xff1a;…

hashmap应用场景_工作中常用到的Java集合有哪些?应用场景是什么?

秋招Java面试大纲&#xff1a;Java并发spring数据库RedisJVMNetty等疫情期间“闭关修炼”&#xff0c;吃透这本Java核心知识&#xff0c;跳槽面试不心慌Spring全家桶笔记&#xff1a;SpringSpring BootSpring CloudSpring MVC前言Java集合是我认为在Java基础中最最重要的知识点…

Zookeeper入门总结

什么是Zookeeper 官方定义&#xff1a; zookeeper是一个分布式服务框架&#xff0c;是Apache Hadoop 的一个子项目&#xff0c;它主要是用来解决分布式应用中经常遇到的一些数据管理问题&#xff0c;如&#xff1a;统一命名服务、状态同步服务、集群管理、分布式应用配置项的管…

rabbitmq启动失败-报Failed to load advanced configuration file解决方法

【README】 1、本文基于 centos8 搭建 rabbitmq&#xff1b; 版本信息如下&#xff1a; rabbitmq rabbitmq-server-3.8.12-1.el8.noarch.rpm erlang erlang 23.2.5 (erts-11.1.8) 上述两者版本一定要强对应&#xff0c;否则mq启动失败&#xff0c;参见官网 https://rabb…

Java抽象类与接口的区别

转载自 Java抽象类与接口的区别 抽象类 抽象类是用来捕捉子类的通用特性的 。它不能被实例化&#xff0c;只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。以JDK中的GenericServlet为例&#xff1a; public abstract class GenericServlet implements Servlet…

gateway坑点:gateway有Controller时会直接处理对应的路径并返回

前言 使用gateway过程中&#xff0c;因为在gateway中加入了一个标注RestController的类&#xff0c;导致请求直接由gateway中的RestController的类处理并返回。花费了几小时才发现问题原因&#xff0c;特此记录 问题 以gateway作为网关转发请求得到的响应&#xff0c;所有字…

电脑任务栏跑到右边去了_电脑没有声音怎么解决 电脑没有声音解决方法【详解】...

电脑没有声音怎么办? 这个话题在我耳边已经听到过了无数次了&#xff0c;处理故障也是由以前的摸索解决到现在可以快速的找到原因。但对于新手朋友来说可能不知道从哪里入手&#xff0c;对于电脑没有声音怎么办&#xff0c;也给不出一个对策&#xff0c;今天围绕这个问题&…