MySQL数据库进阶第二篇(索引,SQL性能分析,使用规则)

文章目录

  • 一、索引概述
  • 二、索引结构
  • 三、结构 - B-Tree
  • 四、结构 - B+Tree
  • 五、结构 - Hash
  • 六、索引分类
  • 七、索引语法
    • 1.案例代码
  • 八、SQL性能分析
    • 1.查看SQl执行频率
    • 2.慢查询日志
    • 3.PROFILES详情
    • 4.EXPLAIN执行计划
  • 九、 索引使用规则
  • 十、SQL 提示
  • 十一、覆盖索引
  • 十二、前缀索引
  • 十三、单列索引&联合索引
  • 十四、索引设计原则

本篇博客深入详细地介绍了数据库索引的概念和重要性。内容包含:索引的概念和目标、索引的优点与缺点。此外,博客还深入解析了三种主要的索引结构:B-Tree、B+Tree和Hash,提供了详细的结构解析和优化方法,并通过插图进一步增强了理解。
博客的部分内容专注于对B-Tree和B+Tree的对比,以及MySQL中索引结构的原理和实际应用。对索引结构的一些微妙差异,如MySQL在B+Tree基础上增加指向相邻叶子节点的链表指针,也进行了深入的探讨。
在对索引结构进行详细解析后,博客介绍了几种不同类型的索引(包括聚簇索引和非聚簇索引)及其适用场景。接着,博客介绍了索引语法,SQL性能分析以及索引直接和索引建议。
总的来说,这篇博客提供了一份详尽且全面的索引教程和指南,从基本概念到实践应用,有很高的参考价值。

一、索引概述

索引是帮助 MySQL 高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查询算法,这种数据结构就是索引。

优点:

提高数据检索效率,降低数据库的IO成本
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
在这里插入图片描述

缺点:

索引列也是要占用空间的
索引大大提高了查询效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE

二、索引结构

在这里插入图片描述
在这里插入图片描述

三、结构 - B-Tree

B-Tree (多路平衡查找树) 以一棵最大度数(max-degree,指一个节点的子节点个数)为5(5阶)的 b-tree 为例(每个节点最多存储4个key,5个指针)

B-Tree结构

在这里插入图片描述

演示地址:https://www.cs.usfca.edu/~galles/visualization/BTree.html

四、结构 - B+Tree

在这里插入图片描述
演示地址:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

与 B-Tree 的区别:
所有的数据都会出现在叶子节点,叶子节点形成一个单向链表

MySQL 索引数据结构对经典的 B+Tree 进行了优化。在原 B+Tree 的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的 B+Tree,提高区间访问的性能。
在这里插入图片描述

五、结构 - Hash

哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称为hash碰撞),可以通过链表来解决。

Hash索引原理图

特点:
Hash索引只能用于对等比较(=、in),不支持范围查询(betwwn、>、<、…)
无法利用索引完成排序操作
查询效率高,通常只需要一次检索就可以了,效率通常要高于 B+Tree 索引

存储引擎支持:
Memory
InnoDB: 具有自适应hash功能,hash索引是存储引擎根据 B+Tree 索引在指定条件下自动构建的

面试题
为什么 InnoDB 存储引擎选择使用 B+Tree 索引结构?
相对于二叉树,层级更少,搜索效率高
对于 B-Tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针也跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低
相对于 Hash 索引,B+Tree 支持范围匹配及排序操作

六、索引分类

在这里插入图片描述
在这里插入图片描述

演示图:
在这里插入图片描述
在这里插入图片描述
聚集索引选取规则:

如果存在主键,主键索引就是聚集索引
如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
如果表没有主键或没有合适的唯一索引,则 InnoDB 会自动生成一个 rowid 作为隐藏的聚集索引

思考题

  1. 以下 SQL 语句,哪个执行效率高?为什么?

select * from user where id = 10;
select * from user where name = ‘Arm’;
– 备注:id为主键,name字段创建的有索引
答:第一条语句,因为第二条需要回表查询,相当于两个步骤。

  1. InnoDB 主键索引的 B+Tree 高度为多少?

答:假设一行数据大小为1k,一页中可以存储16行这样的数据。InnoDB 的指针占用6个字节的空间,主键假设为bigint,占用字节数为8.
可得公式:n * 8 + (n + 1) * 6 = 16 * 1024,其中 8 表示 bigint 占用的字节数,n 表示当前节点存储的key的数量,(n + 1) 表示指针数量(比key多一个)。算出n约为1170。

如果树的高度为2,那么他能存储的数据量大概为:1171 * 16 = 18736;
如果树的高度为3,那么他能存储的数据量大概为:1171 * 1171 * 16 = 21939856。

另外,如果有成千上万的数据,那么就要考虑分表,涉及运维篇知识。

七、索引语法

在这里插入图片描述
创建索引:
CREATE [ UNIQUE | FULLTEXT ] INDEX index_name ON table_name (index_col_name, …);
如果不加 CREATE 后面不加索引类型参数,则创建的是常规索引

查看索引:
SHOW INDEX FROM table_name;

删除索引:
DROP INDEX index_name ON table_name;

1.案例代码

在这里插入图片描述

代码如下(示例):

-- name字段为姓名字段,该字段的值可能会重复,为该字段创建索引
create index idx_user_name on tb_user(name);
-- phone手机号字段的值非空,且唯一,为该字段创建唯一索引
create unique index idx_user_phone on tb_user (phone);
-- 为profession, age, status创建联合索引
create index idx_user_pro_age_stat on tb_user(profession, age, status);
-- 为email建立合适的索引来提升查询效率
create index idx_user_email on tb_user(email);
-- 删除索引
drop index idx_user_email on tb_user;

八、SQL性能分析

1.查看SQl执行频率

在这里插入图片描述
SHOW GLOBAL STATUS LIKE ‘COM_____’

2.慢查询日志

在这里插入图片描述

3.PROFILES详情

在这里插入图片描述
SHOW PROFILES

4.EXPLAIN执行计划

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

九、 索引使用规则

1.最左前缀法则
如果索引关联了多列(联合索引),要遵守最左前缀法则,最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。
如果跳跃某一列,索引将部分失效(后面的字段索引失效)。

2.联合索引中,出现范围查询(<, >),范围查询右侧的列索引失效。可以用>=或者<=来规避索引失效问题。

3.在索引列上进行运算操作,索引将失效。如:explain select * from tb_user where substring(phone, 10, 2) = ‘15’;

4.字符串类型字段使用时,不加引号,索引将失效。如:explain select * from tb_user where phone = 17799990015;,此处phone的值没有加引号

5.模糊查询中,如果仅仅是尾部模糊匹配,索引不会是失效;如果是头部模糊匹配,索引失效。如:explain select * from tb_user where profession like ‘%工程’;,前后都有 % 也会失效。

6.用 or 分割开的条件,如果 or 其中一个条件的列没有索引,那么涉及的索引都不会被用到。

7.如果 MySQL 评估使用索引比全表更慢,则不使用索引。

十、SQL 提示

是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的。

例如,使用索引:
explain select * from tb_user use index(idx_user_pro) where profession=“软件工程”;
不使用哪个索引:
explain select * from tb_user ignore index(idx_user_pro) where profession=“软件工程”;
必须使用哪个索引:
explain select * from tb_user force index(idx_user_pro) where profession=“软件工程”;

use 是建议,实际使用哪个索引 MySQL 还会自己权衡运行速度去更改,force就是无论如何都强制使用该索引。

十一、覆盖索引

在这里插入图片描述
尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能找到),减少 select *。

explain 中 extra 字段含义:
using index condition:查找使用了索引,但是需要回表查询数据
using where; using index;:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询

如果在聚集索引中直接能找到对应的行,则直接返回行数据,只需要一次查询,哪怕是select *;如果在辅助索引中找聚集索引,如select id, name from xxx where name=‘xxx’;,也只需要通过辅助索引(name)查找到对应的id,返回name和name索引对应的id即可,只需要一次查询;如果是通过辅助索引查找其他字段,则需要回表查询,如select id, name, gender from xxx where name=‘xxx’;
在这里插入图片描述

所以尽量不要用select *,容易出现回表查询,降低效率,除非有联合索引包含了所有字段

面试题:一张表,有四个字段(id, username, password, status),由于数据量大,需要对以下SQL语句进行优化,该如何进行才是最优方案:
select id, username, password from tb_user where username=‘itcast’;

解:给username和password字段建立联合索引,则不需要回表查询,直接覆盖索引

十二、前缀索引

当字段类型为字符串(varchar, text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率,此时可以只降字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。

语法:create index idx_xxxx on table_name(columnn(n));
前缀长度:可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。
求选择性公式:

select count(distinct email) / count() from tb_user;
select count(distinct substring(email, 1, 5)) / count(
) from tb_user;
show index 里面的sub_part可以看到接取的长度
在这里插入图片描述

十三、单列索引&联合索引

单列索引:即一个索引只包含单个列
联合索引:即一个索引包含了多个列
在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,而非单列索引。

单列索引情况:
explain select id, phone, name from tb_user where phone = ‘17799990010’ and name = ‘韩信’;
这句只会用到phone索引字段

注意事项
多条件联合查询时,MySQL优化器会评估哪个字段的索引效率更高,会选择该索引完成本次查询
在这里插入图片描述

十四、索引设计原则

在这里插入图片描述

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

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

相关文章

滚动加载react-infinite-scroll-component

react-infinite-scroll-component 当请求数据量过大时&#xff0c;接口返回数据时间会很长&#xff0c;数据回显时间长&#xff0c;Dom 的渲染会有很大的性能压力。 antd的List组件中有提到一个滚动加载的组件库react-infinite-scroll-component 实现滚动加载 Antd&#xff1…

考研高数(高阶导数的计算)

1.归纳法 常见高阶导数 2.泰勒展开式 3.莱布尼兹公式 4.用导数定义证明导函数在某一点连续的例题

【kubernetes】二进制部署k8s集群之cni网络插件flannel和calico工作原理(中)

↑↑↑↑接上一篇继续部署↑↑↑↑ 目录 一、k8s集群的三种接口 二、k8s的三种网络模式 1、pod内容器之间的通信 2、同一个node节点中pod之间通信 3、不同的node节点的pod之间通信 Overlay Network VXLAN 三、flannel网络插件 1、flannel插件模式之UDP模式&#xff0…

2024/2/22

P8680 [蓝桥杯 2019 省 B] 特别数的和 题目描述 小明对数位中含有 2、0、1、9 的数字很感兴趣&#xff08;不包括前导 00&#xff09;&#xff0c;在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40&#xff0c;共28 个&#xff0c;他们的和是574。 请问&#xff0c;在…

【2024软件测试面试必会技能】

Unittest(5)&#xff1a;unittest_忽略用例 忽略用例 在执行测试脚本的时候&#xff0c;可能会有某几条用例本次不想执行&#xff0c;但又不想删也 不想注释&#xff0c;unittest通过忽略部分测试用例不执行的方式&#xff0c;分无条件忽略和有条 件忽略,通过装饰器实现所描述…

Vue3+vite搭建基础架构(11)--- 菜单栏功能和Tab页功能实现

Vue3vite搭建基础架构&#xff08;11&#xff09;--- 菜单栏功能和Tab页功能实现 说明删除项目中不需要的文件userStore全局属性代码菜单栏代码Tab页代码解决浏览器输入地址时不会打开tab页问题和切换tab页时参数丢失问题 说明 这里记录下自己在Vue3vite的项目使用less来写样式…

统信UOS_麒麟KYLINOS上监控网络:探索Smokeping的强大功能

原文链接&#xff1a;统信UOS|麒麟KYLINOS上监控网络&#xff1a;探索Smokeping的强大功能 在当今的网络环境中&#xff0c;无论是个人用户还是企业用户&#xff0c;都非常重视网络的稳定性和连通性。特别是在进行远程工作、在线会议、云计算等活动时&#xff0c;网络质量直接影…

程序员必备技能----删库跑路大总结

删库跑路大总结&#xff0c;各个都是大杀器&#xff0c;破坏性太大&#xff0c;轻易不要尝试。 删除linux根目录&#xff0c;用户目录&#xff0c;其实还可以增加一个删除/etc。删除&#xff08;清除&#xff09;数据库。删除redis缓存和持久化文件。删除mongodb库。git push …

说一说Eclipse的项目类型和常用项目的区别

Eclipse在新建项目的时候有很多类型&#xff0c;包括Java project、Web project等等&#xff0c;如下&#xff1a; 那么这些项目类型有什么区别呢&#xff1f;我们在创建项目的时候应该如何选择&#xff0c;了解清楚这一点还是非常重要的&#xff0c;但记住一个出发点&#xff…

2.22 day3、4 QT

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示"登录成功”&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&…

【论文解读】Uncertainty Quantification of Collaborative Detection for Self-Driving

Uncertainty Quantification of Collaborative Detection for Self-Driving 摘要引言方法问题定义方法概览Double-M 实验结论 摘要 在联网和自动驾驶汽车(CAVs)之间共享信息从根本上提高了自动驾驶协同目标检测的性能。然而&#xff0c;由于实际挑战&#xff0c;CAV 在目标检测…

十九、图像的放缩和插值

项目功能实现&#xff1a;对一张图像进行放大和缩小操作 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 resizing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class RESIZING { public:void resizing(Mat& image); };#pragma…

解决Edge浏览器,微博无法查看大图(Edge Image Viewer)

使用Edge浏览器浏览微博或其它带校验的图片时&#xff0c;会导致无法查看。 主要原因为Edge自带了一个Edge Image Viewer, 但是该图片查看器无法查看带校验数据的图片&#xff0c;所以导致查看时一片空白。 解决方法 地址栏输入 edge://flags/搜索 Edge Image Viewer选择 Disa…

HTML5 Canvas 限定文本区域大小,文字自动换行,自动缩放

<!DOCTYPE html> <html> <body><h1>HTML5 Canvas 限定文本展示范围、自动计算缩放字体大小</h1><div id"tips">0</div> <div id"content">良田千顷不过一日三餐广厦万间只睡卧榻三尺良田千顷不过一日三餐…

【GStreamer】GstElement详解:GStreamer 中最重要的对象

1、什么是元素GstElement? 每个解码器、编码器、解复用器、视频或音频输出实际上都是一个GstElement。GstElement可以视为一个黑盒子:例如,对于解码器元素,输入为已编码数据,输出为解码后的数据,解码过程已由GstElement封装好。 2、都有哪些元素GstElement? 2.1 源点…

概率基础——几何分布

概率基础——几何分布 介绍 在统计学中&#xff0c;几何分布是描述了在一系列独立同分布的伯努利试验中&#xff0c;第一次成功所需的试验次数的概率分布。在连续抛掷硬币的试验中&#xff0c;每次抛掷结果为正面向上的概率为 p p p&#xff0c;反面向上的概率为 1 − p 1-p …

RM电控讲义【HAL库篇】

这段代码中do while的作用&#xff1a; 宏定义中的语句块&#xff1a;do { ... } while (0) 允许你在宏定义中创建一个语句块&#xff0c;从而可以包含多条语句。这在宏定义中特别有用&#xff0c;因为宏只是简单的文本替换&#xff0c;不像函数那样有作用域和返回类型。因此&…

WordPress后台自定义登录和管理页面插件Admin Customizer

WordPress默认的后台登录页面和管理员&#xff0c;很多站长都想去掉或修改一些自己不喜欢的功能&#xff0c;比如登录页和管理页的主题样式、后台左侧菜单栏的某些菜单、仪表盘的一些功能、后台页眉页脚某些小细节等等。这里boke112百科推荐这款可以让我们轻松自定义后台登录页…

2.20日学习打卡----初学Vue3

2.20日学习打卡 目录: 2.20日学习打卡Vue是什么&#xff1f;安装vue模板语法条件渲染列表渲染事件处理表单输入绑定组件基础Props组件交互自定义事件组件交互组件生命周期Vue引入第三方Axios网络请求Axios网络请求封装网络请求跨域解决方案路由配置路由传递参数嵌套路由配置Vue…