探秘MySQL——全面了解索引、索引优化规则

news2024/11/29 4:38:40

文章目录

  • 0.什么是索引
  • 1.常用索引分类
    • 逻辑维度
    • 底层数据结构维度
    • 物理维度(InnoDB)
  • 2.为什么底层是B+树
    • 平衡二叉查找树
    • 红黑树
    • B树(多叉)
    • B+树(多叉)
  • 3.MySQL索引优化
    • SQL性能分析之explain
    • Q.MySQL如何查看查询是否用到了索引
    • 优化一:为表添加自增主键
    • 优化二:添加唯一索引
    • 优化三:添加联合索引
    • Q.索引失效场景:联合索引非连续
    • 优化四:针对order by的优化
    • Q.索引失效场景:order by同时使用ASC 和 DESC
    • Q.性别字段适合添加索引吗
  • 参考

本博客实战部分仓库:点击跳转github

0.什么是索引

索引是帮助MySQL高效获取数据的数据结构。简单来讲,数据库索引就像是书前面的目录,能加快数据库的查询速度。
对于海量数据来说,它的目录也是很大的,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中

1.常用索引分类

逻辑维度

- 唯一索引、主键索引:值唯一,前者可以为null,后者不能为null
- 联合(组合)索引:为多个字段创建的索引,遵循左前缀原则,即从最左边的字段开始匹配
- 普通索引:没什么限制,可重复可为空,都行

底层数据结构维度

hash索引:适用于= <> != IN几种情况,精确查找。仅Memory搜索引擎支持。
B+树索引:适用于范围查找。InnoDBMyISAM支持。

物理维度(InnoDB)

InnoDB提供的一种分类方式,InnoDB的每张表都会有一个聚集索引,有且仅有一个,这也是该表的物理存储方式;非聚集索引可以有多个。

- 聚簇索引(主键索引):
根据主键构建的索引叫做聚簇索引。将数据存储与索引放到了一块,找到索引也就找到了数据。
优点:检索速度很快,排序查找、范围查找都很不赖;没有回表查询现象。
缺点:主键最好是自增的,因为连续的主键索引性能更好;主键最好设置为不可变,改变主键会导致聚集索引的维护代价很高。

- 非聚簇索引(辅助索引):
不是根据主键构建的索引叫做非聚集索引或者二级索引或者辅助索引。
将数据与索引分开存储,索引结构的叶子节点指向了数据对应的位置。
缺点:存在回表查询现象

在这里插入图片描述

在这里插入图片描述

2.为什么底层是B+树

在探讨这个问题前我们先明确一件事: 对于索引的树结构,每个节点称为页,页就是我们上面说的磁盘块,是MySQL数据读取的基本单位。因此,一个节点的读取对应于一次IO操作,底层数据结构的设计应该往减少IO次数的方向进行优化。

如果不知道这几种数据结构的,建议先面向百度学习一下,这不是本文的重点。

平衡二叉查找树

- 缺点:
路数太少,树太深,检索性能有限,而且会导致查找过程中IO次数很多。

在这里插入图片描述

红黑树

- 缺点:
1 同样的,路数太少,树太深,检索性能有限;
2 另外,红黑树不是绝对平衡,IO次数会不稳定。
其实所有的二叉树都有类似的局限性。

在这里插入图片描述

B树(多叉)

- 优点:
1 路数比较多,成功地将二叉树的瘦长结构优化成了矮胖结构,极大地减少了IO查询次数。
2 另外,叶节点都在同一层上,IO次数是比较稳定的。
其实B树已经比较理想了,那为啥MySQL索引没用B树呢?
- 不足:
1 每个非叶节点存储的是索引+数据,其中数据是一条记录,
试想一下,如果一条记录属性非常多,那么B树的每个节点能存储的数据就会变少,
面对海量的数据,最后B树就会从矮胖型变成瘦长型,IO次数势必无法得到优化
2 注意看叶节点层,不同节点不是连续的,当我们需要进行快速范围检索的时候,B树恐怕无法满足我们的要求。

在这里插入图片描述

B+树(多叉)

- 优点:
1 非叶节点仅存储索引,不存储数据,每个节点可存储较多索引值,因此可保证树是矮胖型的,IO次数得到优化
2 叶节点全部在同一层,IO次数十分稳定
3 叶节点保存索引+数据,并且增加了双循环链表的支持,可支持快速范围检索

在这里插入图片描述

为什么底层是B+树,现在知道原因了吧,这种设计是不是很巧妙?

3.MySQL索引优化

光了解理论也没什么意思,直接实战。这部分请 下载我在文章一开始提供的github仓库源码,里面有必要的数据。

由于频繁插入数据会导致索引维护代价很大,因此,我没在创建表时添加索引,而是在插入大量数据结束后再手动添加索引。

SQL性能分析之explain

explain可以分析一条sql的优劣,通过mysql反馈我们,需要我们自己去读懂explain的sql执行结果来判断是否要进行优化。

  • 使用:
explain sql语句;

建议先看看这个老哥的博客,了解下explain方便我们调优。

Q.MySQL如何查看查询是否用到了索引

执行explain语句,查看结果中的type字段(使用到的索引类型)、possible_keys字段(可用索引,未必是最终使用的)、key字段(实际使用的索引)。

优化一:为表添加自增主键

我的三张表都是使用的InnoDB存储引擎,上面提到了,InnoDB会默认为每张表建立一个聚集索引(主键索引) ,这个聚集索引会以主键为键。因此主键建议自增,且最好不要修改,否则索引维护代价很大。

优化必要性:设置自增主键更加符合主键索引的底层特性(有序、范围查找),使其发挥最高检索效率。并且自增主键后期不建议进行修改。

考虑到我的三张表都没有设置主键自增,因此这是我针对数据库需要优化的第一个地方。

在这里插入图片描述

  • 表结构修改思路:原id重命名,重新添加自增主键

仅展示一张表

-- ----------------------------
-- 优化1:设置主键自增
-- ----------------------------
DROP TABLE IF EXISTS `claim`;
CREATE TABLE `claim`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `app_no` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `tree` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

重构表结构之后,再执行data.sql插入数据。

优化二:添加唯一索引

注意:插入大量数据之后再设置索引,可以避免索引的频繁维护。

请看claim这张表,这个app_no字段是唯一的,考虑到我需要经常查询这个字段,我给它设置一个唯一索引。

ALTER TABLE claim
ADD UNIQUE INDEX(app_no);

在这里插入图片描述

text表中的index字段也是同理:

ALTER TABLE text
ADD UNIQUE INDEX(`index`);

优化三:添加联合索引

联合索引数据存储方式:先对索引中第一列的数据进行排序,而后在满足第一列数据排序的前提下,再对第二列数据进行排序,以此类推。

优化规则:

1 考虑选择性:选择性=count(distinct 字段名)/count(*)
将选择性最高的列放到索引最前列(但是不是绝对的)。
2 把经常同时出现在where and子句中的字段设置成联合索引
ALTER TABLE text ADD INDEX id_app_no(`id`,application_no,date);

SELECT * FROM text 
WHERE `id`>1 AND application_no>'EP2567834' AND date>'20170614';

Q.索引失效场景:联合索引非连续

建立联合索引(a,b,c),where c = 5是否会用到索引?为什么?
用不到,因为联合索引遵循左匹配原则,where c=5子句中联合索引直接从a断开了,所以用不到该联合索引。

优化四:针对order by的优化

  • 可优化的情况:
# 查询语句
explain select * from text 
where application_no>'EP2567834' and date>'20170614' 
order by id;

针对这种情况,建立联合索引(application_no,date,id)能命中索引:

注意:where子句中出现的字段放前面,order by中的字段放后面,效率会更高。

alter table text add index app_no_id(application_no,date,`id`);

Q.索引失效场景:order by同时使用ASC 和 DESC

以下情况索引会无法命中:

SELECT FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

Q.性别字段适合添加索引吗

不适合

性别字段因为可重复肯定只能建立非聚集索引,然而因为非聚集索引叶子节点存储的是索引值和聚集索引值,需要回表。所以在性别这种辨别度较低的字段上建立索引,索引树可能只有两个节点,跟线性查找没有太大区别,并且因为回表的存在导致在聚集索引树和非聚集索引树来回切换反而导致查询时间更慢。并且维护该索引还要一定的开销。

参考

博客1
博客2
博客3

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

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

相关文章

fastdfs提高系统连接数

1.操作系统 vi /etc/systemd/system.conf 修改后重启系统。 ulimit -n 验证是否生效。 2.tracker ①docker exec -it trackerID bin/bash ②vi /etc/fdfs/tracker.conf 一般性能测试场景可配置10000 3.storage ①docker exec -it storageID bin/bash ②vi /etc/fdfs/st…

k8s-Pod域名学习总结

k8s-Pod域名学习总结 大纲 k8s内置DNS服务 配置Pod的域名服务 CornDNS配置 默认Pod的域名 自定义Pod的域名 实战需求 1 Pod有自己的域名 2 集群内部的Pod可以通过域名访问其他的Pod 基础准备&#xff1a; 1 k8s 集群版本1.17 k8s内置DNS服务 k8s1.17安装完成后自动创建…

保姆级使用PyTorch训练与评估自己的MixMIM网络教程

文章目录前言0. 环境搭建&快速开始1. 数据集制作1.1 标签文件制作1.2 数据集划分1.3 数据集信息文件制作2. 修改参数文件3. 训练4. 评估5. 其他教程前言 项目地址&#xff1a;https://github.com/Fafa-DL/Awesome-Backbones 操作教程&#xff1a;https://www.bilibili.co…

【python】如何用canvas在自己设计的软件上作画

文章目录前言Canvas组件Canvas画布界面画长方体画多边形PhotoImage组件展示gif的图片展示gif法2总结前言 python学习之路任重而道远&#xff0c;要想学完说容易也容易&#xff0c;说难也难。 很多人说python最好学了&#xff0c;但扪心自问&#xff0c;你会用python做什么了&a…

数据结构——线性数据结构(C语言实现顺序表详解)

1.什么线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串等… 在讲顺序表之前&#xff0c;我们先大致了解一下线性表。…

qt .pro文件 qmake编译过程

#&#xff1a;注释一行 QT&#xff1a;此项目中使用的Qt modules列表 CONFIG&#xff1a;此项目中使用的配置选项 TARGET&#xff1a;目标输出文件的名字 TEMPLATE&#xff1a;当生成二进制文件时项目的模版&#xff0c;例如app,lib 平台下使用 windows { SOURCES SysInf…

剑指 Offer II 024. 反转链表

题目链接 剑指 Offer II 024. 反转链表 easy 题目描述 给定单链表的头节点 head&#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;h…

不用费劲,这5款效率工具为你解决学习工作烦恼

今天我要向大家推荐5款超级好用的效率软件&#xff0c;无论是在学习还是办公中都能够极大地提高效率。这些软件可以帮助你解决许多问题&#xff0c;而且每个都是真正的神器。 1.键盘仿真鼠标——NeatMouse NeatMouse 是一个小型的工具能够使用鼠标光标控制指针。当你的鼠标不…

python编程基础

python编程基础 1、什么是编程语言&#xff1f; 编程语言是用来控制计算机的一系列指令&#xff08;Instruction&#xff09;&#xff0c;它有固定的格式和词汇&#xff08;不同编程语言的格式和词汇不一样&#xff09;&#xff0c;必须遵守&#xff0c;否则就会出错&#xf…

opencv加水印

本文介绍opencv给图片加水印的方法。 目录1、添加水印1.1、铺满1.2、在指定区域添加1.3、一比一铺满1、添加水印 添加水印的原理是调低两张图片的透明度&#xff0c;然后叠加起来。公式如下&#xff1a; dst src1 * opacity src2 * (1 - opacity) gamma; opacity是透明度&a…

UE官方教程笔记02-实时渲染基础下

对官方教程视频[官方培训]02-实时渲染基础下 | 陈拓 Epic的笔记没听懂的地方就瞎写反射实时渲染中反射是一个非常有挑战的特性UE中有多种不同的方案&#xff0c;各有各的优势和缺点反射捕获屏幕空间反射平面反射LumenRT Reflection反射捕获在指定位置捕获一张Cube Map需要预计算…

低代码:助力乡村振兴事业开启“智慧模式”

伴随着脱贫攻坚目标任务的全面完成&#xff0c;我国“三农”工作重心历史性地转向全面推进乡村振兴&#xff0c;这也标志着我国农业农村工作迈上了一个新台阶。 什么是乡村振兴&#xff1f; 乡村振兴是新时代“三农”工作的总抓手&#xff0c;坚持农业农村优先发展&#xff0c;…

windows 下docker 安装clickhouse

docker 下载https://www.docker.com/products/docker-desktop/将下载下来的Docker Desktop Installer.exe文件双击进行安装即可&#xff0c;安装完成后&#xff0c;任务栏会出现一个蓝色的小鲸鱼图标&#xff08;注意安装完成后可能会重启系统&#xff09;Docker Desktop如果出…

禁用XXE处理漫谈

前言 近期准备面试题时&#xff0c;XXE漏洞防范措施&#xff08;或者说修复方式&#xff09;在一些文章中比较简略&#xff0c; 故本文根据研究进行总结&#xff0c;作为技术漫谈罢了。 简述 XXE漏洞 XXE&#xff08;XML外部实体注入&#xff09;&#xff0c;程序解析XML数…

国产8K摄像机拍摄回顾与画面数据反馈

本文分析两款国产8K摄像机&#xff0c;一款是全画幅&#xff0c;一款是M43画幅。一、全新国产全画幅8K B1机器参数数据汇总&#xff1a;全画幅8K 60fps&#xff0c;受益于8K全画幅的优势与大幅升级的图像处理系统&#xff0c;BOSMA 8K摄像机系统提升到新的高度。拍摄支持&#…

Ubuntu 安装 CUDA and Cudnn

文章目录0 查看 nvidia驱动版本1 下载Cuda2 下载cudnn参考&#xff1a;0 查看 nvidia驱动版本 nvidia-smi1 下载Cuda 安装之前先安装 gcc g gdb 官方&#xff1a;https://developer.nvidia.com/cuda-toolkit-archive&#xff0c;与驱动版本进行对应&#xff0c;我这里是12.0…

C++语法规则1(C++面向对象 )

C面向对象 面向对象的三大特征是继承&#xff0c;多态和封装&#xff0c;C重面向对象重要的就是这些&#xff0c;我们下面通过一些简单的实例加以理解&#xff0c;从这小节开始&#xff0c;我们将开启新的编程旅途。与 C 语言编程的思想完全不同了&#xff0c;这就是 C!理解概…

[Linux基础]history相关的环境变量设置

目录 背景 简介 命令操作 1. 语法&#xff1a; 2. 功能 3. 参数 环境变量设置 背景 工作中时常收到客户的反馈&#xff0c;我的系统什么也没干&#xff0c;就出现文件丢失&#xff0c;程序错误等等问题&#xff1b;我们在问题排查的时候查看history信息也是重要环节…

大数据导论、Apache ZooKeeper

目录标题1、数据与数据分析2、数据分析基本步骤3、大数据时代4、分布式技术5、 Apache ZooKeeper5.1 ZooKeeper 概述5.2 ZooKeeper 特性5.3 ZooKeeper 集群角色5.4 ZooKeeper 集群搭建5.5 ZooKeeper 数据模型1、数据与数据分析 数据分析是指用适当的统计分析方法对收集来的数据…

零基础小白如何自学网络安全成为顶尖黑客?

在成为黑客之前&#xff0c;你需要做两点准备&#xff1a; 1、学一门编程语言。学哪一门不重要&#xff0c;但你要参考一下下面的条例&#xff1a; C语言是Unix系统的基础。它&#xff08;连同汇编语言&#xff09;能让你学习对黑客非常重要的知识&#xff1a;内存的工作原理…