【MySQL】之索引与索引优化

news2024/12/23 22:54:15

目录

  • 一、索引介绍
  • 二、MySQL索引结构
  • 二、索引优化

一、索引介绍


1、索引简介

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构

可以得到索引的本质:索引是数据结构。索引的目的在于提高查询效率,就好像我们平常使用的字典一样。我们可以简单理解为索引是排好序的快速查找结构

在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。下图就是一种可能的索引方式示例:

在这里插入图片描述

左边是数据表,一共有两列七条记录,Col1 是数据记录的物理地址,Col2 是记录的数据,为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上.

我们平常所说的索引,如果没有特别指明,都是指B+树结构组织的索引。其中聚集索引,次要索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引。当然,除了B+树这种类型的索引之外,还有哈稀索引(hash index)等。

2、索引的优缺点

优点

  • 类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本
  • 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗

缺点

  • 实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的
  • 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息
  • 索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句

3、MySQL索引分类

  • 单值索引:即一个索引只包含单个列,一个表可以有多个单列索引
  • 唯一索引:索引列的值必须唯一,但允许有空值
  • 复合索引:即一个索包含多个列

4、索引相关语句

  • 创建

    CREATE  [UNIQUE ] INDEX indexName ON mytable(columnname(length)); 
    ALTER mytable ADD  [UNIQUE ]  INDEX [indexName] ON (columnname(length));
    
  • 删除

    DROP INDEX [indexName] ON mytable; 
    
  • 查看

    SHOW INDEX FROM table_name\G;
    
  • 使用 ALTER 命令

    -- 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
    ALTER TABLE tbl_name ADD PRIMARY KEY (column_list);
    
    -- 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)
    ALTER TABLE tbl_name ADD UNIQUE index_name (column_list);
    
    -- 添加普通索引,索引值可出现多次
    ALTER TABLE tbl_name ADD INDEX index_name (column_list);
    
    -- 该语句指定了索引为 FULLTEXT ,用于全文索引
    ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list);
    

二、MySQL索引结构


1、MySQL 的索引结构包含有:

  • B/B+Tree索引
  • Hash索引
  • full-text全文索引
  • R-Tree索引

2、B+Tree 索引的检索原理

B+Tree索引的检索原理图如下:

在这里插入图片描述

【初始化介绍】

一颗b+树,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3。

P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。

真实的数据存在于叶子节点,即3、5、9、10、13、15、28、29、36、60、75、79、90、99,非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

【查找过程】

  1. 如果要查找数据项为29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO;
  2. 在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO;
  3. 29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。


三、索引优化


1、索引创建场景

需要创建索引的情况

  • 主键自动建立唯一索引
  • 频繁作为查询条件的字段应该创建索引
  • 查询中与其它表关联的字段,外键关系建立索引
  • 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  • 查询中统计或者分组字段
  • 单值/组合索引的选择问题:在高并发下倾向创建组合索引

不需要创建索引的情况

  • 表记录太少
  • 经常增删改的表:提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
  • 频繁更新的字段不适合创建索引,因为每次更新不单单是更新了记录还会更新索引,加重了IO负担
  • Where条件里用不到的字段不创建索引
  • 数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据列建立索引(如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果)。

2、避免索引失效

  • 尽量全值匹配,对于字符串来说,全值匹配时命中索引几率是最高的
  • 遵循最佳左前缀法则:如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列
  • 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
  • 避免出现存储引擎不能使用索引中范围条件右边的列
  • 尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少使用 select *
  • mysql 在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描
  • is null,is not null 也无法使用索引
  • like 如果以通配符开头(‘%abc…’),会导致mysql索引失效,而变成全表扫描的操作
  • 字符串不加单引号索引失效
  • 少用or,用它来连接时会索引失效

3、索引优化建议

  • 永远小表驱动大表,即小的数据集驱动大的数据集
  • 对于单键索引,尽量选择针对当前query过滤性更好的索引
  • 在选择组合索引的时候,当前Query中过滤性最好的字段在索引字段顺序中,位置越靠前越好
  • 在选择组合索引的时候,尽量选择可以能够包含当前query中的where字句中更多字段的索引
  • 尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的
  • 少用 Hint 强制索引

4、关键命令优化

1、order by关键字优化

  • ORDER BY子句,尽量使用Index方式排序,避免使用FileSort方式排序。MySQL支持二种方式的排序,FileSort和Index,Index效率高,因为它指示MySQL扫描索引本身完成排序,而FileSort方式效率较低。
  • ORDER BY 满足两情况,会使用Index方式排序:
    • 1、ORDER BY 语句使用索引最左前列;
    • 2、使用Where子句与Order BY子句条件列组合满足索引最左前列。
  • 尽可能在索引列上完成排序操作,遵照索引建的最佳左前缀
  • 如果不在索引列上,filesort 有两种算法:双路排序和单路排序
    • 双路排序:MySQL 4.1之前是使用双路排序,字面意思就是两次扫描磁盘,最终得到数据,读取行指针和orderby列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出
    • 单路排序:从磁盘读取查询需要的所有列,按照order by列在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了。
  • 优化策略:
    • 增大max_length_for_sort_data参数的设置:不管用哪种算法,提高这个参数都会提高效率,当然,要根据系统的能力去提高,因为这个参数是针对每个进程的
    • 增大sort_buffer_size参数的设置:提高这个参数, 会增加用改进算法的概率。但是如果设的太高,数据总容量超出sort_buffer_size的概率就增大,明显症状是高的磁盘I/O活动和低的处理器使用率

2、GROUP BY关键字优化

  • group by 实质是先排序后进行分组,遵照索引建的最佳左前缀
  • 当无法使用索引列,增大 max_length_for_sort_data 参数的设置 + 增大 sort_buffer_size 参数的设置
  • where高于having,能写在where限定的条件就不要去having限定了。

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

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

相关文章

高考状元、通用语言和轰趴-UMLChina建模知识竞赛第4赛季第4轮

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。第4题为附加题&#xff0c;对错不影响获奖&#xff0c…

Springboot使用pdfbox提取PDF图片

Springboot使用pdfbox提取PDF图片 PDFBox的介绍Springboot集成PDFBox一、提取pdf首页为图像1. 实现需求2. 项目代码3. 执行结果 二、将pdf内容全部转换为图像1. 实现需求2. 项目代码3. 执行结果4.注意事项1.优化项目代码2.提升Java heap size PDFBox的介绍 PDFBox是一个用于创…

FDM3D打印系列——1、愉快的给自己打印一个手办

大家好&#xff0c;我是阿赵。 我日常的个人爱好&#xff0c;除了写博客&#xff0c;还有弹吉他打鼓电子琴&#xff0c;还有3D打印。 3D打印只是我的一个业余&#xff0c;不过由于经常把做好的作品发朋友圈&#xff0c;也带动了身边一些朋友买了和我一样型号的打印机&#xff0…

一种说法:哲学是研究真善美的

一种说法&#xff1a;哲学是研究真、善、美的 今天在工作中谈到了真善美 确定一个企业价值观&#xff1a;求真&#xff0c;求善&#xff0c;求美 我觉得挺好&#xff0c;起码无需解释能懂意思 趣讲大白话&#xff1a;真善美是基本问题 【趣讲信息科技199期】 *****************…

用Python做一个下载器,从获取数据到编写GUI界面

本片文章目录 前言案例基本实现思路?代码实现一、单张小说下载二、整本小说下载三、多线程采集四、采集排行榜所有小说五、搜索小说功能六、GUI界面 尾语 前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 对于广大书虫而言&#xff0c;没有小说看是最痛苦的&#xff0…

English Learning - L3 作业打卡 Lesson6 Day42 2023.6.15 周四

English Learning - L3 作业打卡 Lesson6 Day42 2023.6.15 周四 引言&#x1f349;句1: In towns that are near the sea, the tiny lanterns which had been hung in the streets the night before, are placed into the water when the festival is over.成分划分弱读连读爆破…

(二叉树) 129. 求根节点到叶节点数字之和 ——【Leetcode每日一题】

❓129. 求根节点到叶节点数字之和 难度&#xff1a;中等 给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表一个数字&#xff1a; 例如&#xff0c;从根节点到叶节点的路径 1 -> 2 -> 3 表示数…

CSS- 横向和纵向时间轴

/*横向时间轴*/.time-horizontal {list-style-type: none;border-top: 1px solid #707070;max-width: 800px;padding: 0px;margin: 0px;}.text-horizontal {list-style-type: none;max-width: 800px;padding: 0px;margin: 0px;}.text-horizontal li {float: left;position: rel…

数据中心网络的电路交换域

buffer 的意义在用带宽平滑统计突发&#xff1a; 流量波动越大&#xff0c;统计复用能效越高。假设没有 buffer&#xff0c;将大量溢出和空载并存。但如果流量是可预期的&#xff0c;也可以转向相反的方向&#xff0c;比如虚电路。 数据中心与 Internet 不同&#xff0c;流量…

90后Android程序员杨国民的羊粪肥创业故事:从社恐到销售奇迹

90后Android程序员杨国民的羊粪肥创业故事&#xff1a;从社恐到销售奇迹 最近一位90后程序员杨国民的创业故事在社交媒体上引起了轰动。他回到了内蒙古老家&#xff0c;并以羊粪肥为主要产品&#xff0c;取得了惊人的销售成绩。据报道&#xff0c;他的羊粪肥月销量达到了120万…

Java选择题刷题记录2

Java集合的关系 图片来自原文链接&#xff1a;https://blog.csdn.net/weixin_45861283/article/details/116201140 HashMap的键可以为null Java基本数据类型&#xff0c;注意String不是基本数据类型 NIO 全称java non-blocking IO &#xff0c;是指 Java 一系列改进的输入…

一篇文章docker-compose安装使用全解

提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 关于docker composedocker compose安装Linux安装docker-composeWindows安装docker-compose docker-compose YMAL常用配置项综合配置示例 docker compose常用命令启动…

设计模式(二十):行为型之迭代器模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

LabVIEW开发移动车辆的识别和特征提取

LabVIEW开发移动车辆的识别和特征提取 闭路电视摄像机在高速公路上变得越来越普遍&#xff0c;并用于交通管理;摄像机允许操作员直观地监控交通状况。随着摄像机数量的增加&#xff0c;操作员监控每个摄像机成为一项艰巨的任务&#xff0c;因此录制视频&#xff0c;并且通常仅…

Hack The Box - Web - Phonebook

玩一会儿htb的challenge&#xff0c;最近找工作&#xff0c;所以先玩玩web类型的。 这道题目的类型有人说是LDAP注入、有人说是like注入。LDAP这玩意08年的时候估计可能比较流行&#xff0c;但是现在应该没多少人用了吧&#xff0c;比较小众。其实LDAP这个特殊的数据库是比较契…

LwIP RAW API 实现UDP多播收发

LwIP RAW API 实现UDP多播收发实现 1、初始化 static struct udp_pcb *multicast_pcb NULL; static ip_addr_t mutlcast_send_ip; static ip_addr_t mutlcast_recv_ip;static void udp_recv_multicast(void *arg, struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *add…

安装cv2库时出现错误的一般解决方法

问题描述&#xff1a; 安装cv2库时出现错误 补充&#xff1a;cv2库的简单介绍 cv2是Python中常用的计算机视觉库OpenCV的Python接口模块。通过使用cv2模块&#xff0c;您可以方便地进行图像和视频的读取、处理和显示等操作。它提供了许多常用的图像处理函数和工具&#xff0…

WPF基础学习笔记3-文本控件

1.文本控件 文本控件System.Windows.Controls,TextBox继承自System.Windows.Controls.TextBoxBase类System.Windows.Controls.RichTextBox继承自System.Windows.Controls.TextBoxBase类 1.1 TextBox 表示一个控件&#xff0c;该控件可用于显示或编辑无格式文本 <Grid>&l…

Python算法练习6.17

leetcode 1768 交替合并字符串 给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 输入&#xff1a;word1 &qu…

【探索 Kubernetes|作业管理篇 系列 9】Pod 的服务对象

前言 大家好&#xff0c;我是秋意零。 在上一篇中&#xff0c;我们介绍了 Pod 的生命周期以及区分 Pod 字段的层次级别&#xff0c;相信你对此有了充分的认识。 今天&#xff0c;我们还会接着以 Pod 展开&#xff0c;说说它的 “服务对象”&#xff0c;一听就知道是对 Pod 提…