MySQL进阶——索引【核心】

目录

1索引概述

2索引结构

2.1 B-Tree(多路平衡查找树)

2.2 B+Tree

2.3 hash

3索引分类

3.1MySQL中分4类

3.2 InnoDB存储引擎分两类(SQL优化中重要)

4索引语法

4.1创建和查看索引

4.2删除索引

5 SQL性能分析

5.1 查看执行频次

5.2慢查询日志

5.3profile详情(慢日志不行可以用这个)

5.4 explain(重要

Linux,MySQL,finalshell都安装好啦!开干!

(1)先启动虚拟机,然后打开远程连接finalshell

(2)输入mysql -u root -p,连接到Linux中的MySQL数据库。就可以在这上面操作Linux-MySQL啦(我是这么理解的)

1索引概述

索引 (index)是帮助MysQL高效获取数据的数据结构(有序)

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

(1)无索引情况:就需要从第一行开始扫描,一直扫描到最后一行,我们称之为全表扫描,性能很低。

(2)有索引情况:如果我们针对于这张表建立了索引,假设索引结构就是二叉树(存储结构),那么也就意味着,会对age这个字段建立一个二叉树的索引结构。此时我们在进行查询时,只需要扫描三次就可以找到数据了,极大的提高的查询的效率。

优缺点:

2索引结构

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种:

上述是MySQL中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持情况:

2.1 B-Tree(多路平衡查找树)

普通的二叉树(理想情况):

普通的二叉树(最糟糕情况——顺序插入):

如果主键是顺序插入的,则会形成一个单向链表,结构如下。

通过红色树来解决上面这个平衡问题,因为红黑树是自平衡的二叉树:

那这样即使是顺序插入数据,最终形成的数据结构也是一颗平衡的二叉树,结构如下。但是红黑树也有缺点:大数据量情况下,层级较深,检索速度慢。

所以,在MySQL的索引结构中,并没有选择二叉树或者红黑树,而选择的是B+Tree

数据结构可视化网(www.cs.usfca.edu)

https://www.cs.usfca.edu/~galles/visualization/BTree.html

随着插入,中间节点往上移。

2.2 B+Tree

B+Tree是B-Tree的变种 ,B+Tree中所有的节点都会出现在叶子节点。

最终我们看到,B+Tree 与 B-Tree相比,B+Tree主要有以下三点区别:

(1)所有的数据都会出现在叶子节点。

(2)叶子节点形成一个单向链表。

(3)非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。

2.3 hash

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

补充数据结构只是,当遇到hash冲突的解决方法:

1、开放定址法:我们在遇到哈希冲突时,去寻找一个新的空闲的哈希地址。

(1)线性探测法

当我们的所需要存放值的位置被占了,我们就往后面一直加1并对m取模直到存在一个空余的地址供我们存放值,取模是为了保证找到的位置在0~m-1的有效空间之中。

(2)平方探测法(二次探测)

当我们的所需要存放值的位置被占了,会前后寻找而不是单独方向的寻找。

2、再哈希法:同时构造多个不同的哈希函数,等发生哈希冲突时就使用第二个、第三个……等其他的哈希函数计算地址,直到不发生冲突为止。虽然不易发生聚集,但是增加了计算时间。

3、链地址法:将所有哈希地址相同的记录都链接在同一链表中。

4、建立公共溢出区:将哈希表分为基本表和溢出表,将发生冲突的都存放在溢出表中。

Hash树特点:

(1) Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,< ,...)

(2)无法利用索引完成排序操作

(3)查询效率高,通常(不存在hash冲突的情况)只需要一次检索就可以了,效率通常要高于B+tree索引

思考题:为什么InnoDB存储引擎选择使用B+tree索引结构?

(1)相对于二叉树,层级更少,搜索效率高;

(2)对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;

(3)相对Hash索引,B+tree支持范围匹配排序操作;

3索引分类

3.1MySQL中分4类

在MySQL数据库,将索引的具体类型主要分为以下几类:主键索引、唯一索引、常规索引、全文索引。

3.2 InnoDB存储引擎分两类(SQL优化中重要)

而在在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:聚集索引和二级索引/辅助索引/非聚集索引。

聚集索引选取规则:

(1)如果存在主键,主键索引就是聚集索引。

(2)如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。

(3)如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

除开聚集索引,其他都是二级索引。索引的叶子节点下挂的是该字段值对应的主键值。

lnnoDB主键索引的B+tree高度为多高呢?

假设:一行数据大小为1k,,一页中可以存储16行这样的数据。InnoDB的指针占用6

个字节的空间,主键即使为bigint,占用字节数为8。

(1)高度为2:

n * 8+(n +1)*6=16*1024,算出n约为1170(每一行的节点个数)

1171*16=18736

(2)高度为3:

1171 * 1771 * 16= 21939856

(发现InnoDB存储就算存储2000多万个记录数,也才3层,检索效率很高)

4索引语法

4.1创建和查看索引

CREATE [ UNIQUE | FULLTEXT ] INDEX index_name ON table_name (index_col_name, . .. ) ;

SHOW INDEX FROM table_name ;

案例:按照下列的需求,完成索引的创建

1. name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。

2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。

3.为profession、age、status创建联合索引。

4.为email建立合适的索引来提升查询效率。

演示

(1)新建itcast数据库,并在其中准备两个表格:

(2)查询tb_user表的索引情况,

在分号之前加上\G,可以转置展示。

(3)完成:1. name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。

输入创建索引语句:create index idx_user_name on tb_user(name);

(因为InnoDB引擎默认是BTree)

(4)完成:2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。

非空,且唯一的就要加上关键字UNIQUE

输入创建索引语句:create unique index idx_user_phone on tb_user(phone);

但是报错了:

猜想是原本的数据库中已经有重复不唯一的两个电话phone了,所以不能满足unique条件。

利用DELETE FROM表名[WHERE条件],删除重复的数据:

现在输入:CREATE UNIQUE INDEX idx_user_phone ON tb_user(phone);

就能成功创建索引:

(5)完成:3.为profession、age、status创建联合索引。

输入:create index idx_user_pro_age_sta on tb_user(profession,age,status);

注意,在联合索引中,字段顺序有讲究的,后面说

(6)完成:4.为email建立合适的索引来提升查询效率。

4.2删除索引

DROP INDEX index_name ON table_name ;

如:删除emai的索引

输入:drop index idx_user_email on tb_user;

5 SQL性能分析

5.1 查看执行频次

SQL优化的主要是查询select语句。MySQL 客户端连接成功后,通过 show [session | global] status 命令可以提供服务器状态信息。

通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次:-- session 是查看当前会话;-- global是查询全局数据;

SHOW GLOBAL STATUS LIKE 'Com_______';

输入:show global status like 'Com_______';(7个_)

5.2慢查询日志

借助慢查询日志,来定位SQL执行效率比较低的语句,从而对这类上SQL语句进行优化

慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有 SQL语句的日志。

MySQL的慢查询日志默认没有开启,我们可以查看一下系统变量 slow_query_log

输入:show variables like 'slow_query_log';发现默认没有开启。

但是我Windows中的mysql是开启状态呢。

开启慢查询日志,利用Linux中的vi编辑器!

在Linux路径而不是mysql路径,输入:vi /etc/my.cnf;

然后按i进入输入状态,按esc退出输入,尾部:x保存并退出,vi操作不是很熟练,后面可能要补一下Linux方面的知识。

输入:systemctl restart mysqld 重新启动mysql,但是我这报错是为啥?

芭比Q了,路径不一样(安装方式不一样)。

课的:cd /var/lib/mysql;

我的:cd /usr/local/mysql/data;

5.3profile详情(慢日志不行可以用这个)

输入:select @@have_profiling;查看。。。

开启之后,查看目前的指令执行耗时情况:

执行一系列SQL之后再次查看当前执行SQL语句耗时情况:show profiles;

可以看到根据主键id查询,比二级索引name查询要快十倍!

查看指定语句的耗费在哪些操作中:show profile for query 10;

还可以查询CPU耗费情况:show profile cpu for query 10;

5.4 explain(重要)

通过时间来判断SQL语句的性能比较粗略,用explain可以查看SQL执行计划,一般通过explain来判断SQL性能。

在select前加上explain或desc就可以查询这个SQL语句的执行计划。

Explain 执行计划中各个字段的含义:

创建多表:

create table student(

    id int auto_increment primary key comment '主键ID',

    name varchar(10) comment '姓名',

    no varchar(10) comment '学号'

) comment '学生表';

insert into student values (null, '黛绮丝', '2000100101'),(null, '谢逊', '2000100102'),(null, '殷天正', '2000100103'),(null, '韦一笑', '2000100104');



create table course(

    id int auto_increment primary key comment '主键ID',

    name varchar(10) comment '课程名称'

) comment '课程表';

insert into course values (null, 'Java'), (null, 'PHP'), (null , 'MySQL') , (null, 'Hadoop');



create table student_course(

    id int auto_increment comment '主键' primary key,

    studentid int not null comment '学生ID',

    courseid  int not null comment '课程ID',

    constraint fk_courseid foreign key (courseid) references course (id),

    constraint fk_studentid foreign key (studentid) references student (id)

)comment '学生课程中间表';



insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,2),(null,2,3),(null,3,4);

id相同,执行顺序从上到下; 但是这里不是一个sc连接两个吗?

id不同,值越大,越先执行:

案例:查询选修了MySQL课程的学生

最先执行c表,找到MySQL的课程id

然后执行sc,找到这个课程id对应的学生id

然后执行s,找到学生id对应的学生信息。

type表示连接类型:

性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、 index、all。

(1)All全表扫描是性能最差的,null是最好的,但是一般不可能优化到null,null表示不调用任何表。如select ‘A’; 连接类型就为null。

(2)使用主键/唯一索引进行查询,类型就是const。

(3)如果使用非唯一索引进行查询,类型就是ref。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu安装docker 详细教程

Ubuntu安装docker&#xff0c;以及docker compose踩了一步一步的坑&#xff0c;真的特别抓马&#xff01;&#xff01;&#xff01; 因此分享我的安装教程和踩坑&#xff0c;希望给大家一些帮助吧 安装详细教程 卸载docker停止 docker 运行使用以下命令来卸载 Docker 软件包及其…

国产数据库中读写分离实现机制

在数据库高可用架构下会存在1主多备的部署&#xff0c;备节点可以根据业务场景分发一部分流量以充分利用资源&#xff0c;并减轻主库的压力&#xff0c;因此在数据库的功能上需要读写分离来实现。 充分利用备节点的资源&#xff0c;提升业务的吞吐量&#xff1b;防止运维等非业…

助力低空经济-eVTOL/无人机ADS-B航管应答机选型指南

一、低空经济概述 “低空经济”在今年全国两会首次写入政府工作报告。近日&#xff0c;工业和信息化部、科学技术部、财政部、中国民用航空局印发《通用航空装备创新应用实施方案&#xff08;2024—2030年&#xff09;》&#xff0c;提出到2030年&#xff0c;推动低空经济形成…

c语言回顾-结构体(2)

前言 前面讲了结构体的概念&#xff0c;定义&#xff0c;赋值&#xff0c;访问等知识&#xff0c;本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段&#xff0c;话不多说&#xff0c;直接上干货&#xff01;&#xff01;&#xff01; 1.结构体内存对齐 说到计…

自建消息推送工具 Gotify 实现消息私有化通知

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 之前分享了如何通过 Webhook 将 VPS 与 NAS 上部署的应用消息推送到钉钉、飞书、企业微信,但是对于部分用户来说,可能因为以下种种原因,不方便使用常见的办公 IM 软件来进行消息推送: 消息涉及隐私敏感信息,不希…

11.6.k8s实战-节点扩缩容

目录 一&#xff0c;需求描述 二、集群缩容-节点下线 1&#xff0c;节点下线案例说明 2&#xff0c;查看现有节点 3&#xff0c;查看所有名称空间下的pod ​编辑4&#xff0c;驱逐下线节点的pod 5&#xff0c;驱逐后再次查看pod 6&#xff0c;驱逐pod后再次查看节点信息…

新书速览|Ubuntu Linux运维从零开始学

《Ubuntu Linux运维从零开始学》 本书内容 Ubuntu Linux是目前最流行的Linux操作系统之一。Ubuntu的目标在于为一般用户提供一个最新的、相当稳定的、主要由自由软件构建而成的操作系统。Ubuntu具有庞大的社区力量&#xff0c;用户可以方便地从社区获得帮助。《Ubuntu Linux运…

熟练一种编程语言再学另一种语言时,叠的是buff还是debuff?

在大多数情况下&#xff0c;尤其是对于广泛使用的高级编程语言&#xff0c;它们之间存在正向的相互促进作用&#xff0c;熟练使用一种语言后再去学习另一种语言&#xff0c;大概率能叠个buff。 首先&#xff0c;学习编程语言的基础是通用的&#xff0c;比如软硬件和网络基础、算…

iOS原生APP开发的技术难点

iOS原生APP开发的技术难点主要体现在以下几个方面&#xff0c;总而言之&#xff0c;iOS原生APP开发是一项技术难度较高的工作&#xff0c;需要开发者具备扎实的编程基础、丰富的开发经验和良好的学习能力。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xf…

shell中的条件判断

在Linux操作系统中如何是用条件判断语句&#xff0c; 如上图所示&#xff0c;先定义一个变量变量值&#xff0c;再使用test $a hello来判断式子的正确与否&#xff0c;当结果正确的时候返回0&#xff0c;当结果错误时候结果返回1&#xff0c;可以是用echo $? 来获取并打印输出…

AI大模型会如何颠覆手机?

导语&#xff1a;大模型在手机端的落地&#xff0c;不仅仅是AI进入人类生活的开始&#xff0c;也是行业发生颠覆&#xff0c;新老巨头进行更替的时刻。 将大模型变小&#xff0c;再塞进手机&#xff0c;会给人们的生活带来怎样的影响&#xff1f; 最近&#xff0c;荣耀成为了…

数据结构历年考研真题对应知识点(单链表、双链表、循环链表)

目录 2.3线性表的链式表示 2.3.1单链表的定义 【单链表的应用(2009、2012、2013、2015、2016、2019)】 2.3.2单链表上基本操作的实现 【单链表插入操作后地址或指针的变化(2016)】 2.3.3双链表 【双链表中插入操作的实现(2023)】 【循环双链表中删除操作的实现(2016)】 …

Ubuntu20.04部署Qwen2.openvino流程

下载代码 里面包含依赖 git clone https://github.com/OpenVINO-dev-contest/Qwen2.openvino.gitpython环境配置 创建虚拟环境 conda create -name qwen2openvino python3.10 conda activate qwen2openvino安装依赖 pip install wheel setuptools pip install -r requirem…

C# OCCT Winform 选中模型改变状态

选中状态设置 _context new AIS_InteractiveContext(_viewer);var selectionDrawer new Prs3d_Drawer();selectionDrawer.SetColor(Colors.Selection);selectionDrawer.SetDisplayMode(1);selectionDrawer.SetTransparency(0.1f);_context.SetSelectionStyle(selectionDrawe…

基于PHP的民宿管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿管理系统 一 介绍 此民宿管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端jquery.js和echarts.js。系统角色分为用户和管理员。用户可以在线浏览和预订民宿&#xff0c;管理员登录后台进行相关管理等。(在系统…

【TB作品】MSP430G2553,单片机,口袋板, 单相交流电压、电流计设计

题5 单相交流电压、电流计设计 设计基于MSP430的单相工频交流电参数检测仪。交流有效值0-220V&#xff0c;电流有效值0-40A。电压、电流值经电压、电流传感器输出有效值为0-5V的交流信号&#xff0c;传感器输出的电压、电流信号与被测电压、电流同相位。 基本要求如下 &#xf…

前端网站(二)-- 菜单页面【附源码直接可用】

菜单页面 开篇&#xff08;请大家看完&#xff09;&#xff1a;此网站写给挚爱&#xff0c;后续页面还会慢慢更新&#xff0c;大家敬请期待~ ~ ~ 轻舟所编写这个前端框架的设计初衷&#xff0c;纯粹是为了哄对象开心。除此之外&#xff0c;并无其它任何用途或目的。 此前端框…

基于Java的二手手机回收平台系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JavaJSPServlet 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展…

【C++提高编程-10】----C++ STL常用拷贝和替换算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Chat-TTS chat-tts-ui 实机部署上手测试!Ubuntu服务器实机 2070Super*2 8GB部署全流程

项目介绍 开源的项目&#xff0c;感谢各位大佬的贡献&#xff01; 官方介绍&#xff1a;一个简单的本地网页界面&#xff0c;使用ChatTTS将文字合成为语音&#xff0c;同时支持对外提供API接口。A simple native web interface that uses ChatTTS to synthesize text into spe…