Mysql(七) --- 索引

文章目录

  • 前言
  • 1.简介
    • 1.1.索引是什么?
    • 1.2.为什么使用索引?
  • 2.索引应该使用什么数据结构?
    • 2.1.Hash
    • 2.2.二叉搜索树
    • 2.3.N叉树
    • 2.4.B+树
      • 2.4.1. 简介
      • 2.4.2. B+树的特点
      • 2.4.3. B+树和B树的对比
  • 3.Mysql中的页
    • 3.1.为什么要使用页
    • 3.2.页文件头和页文件尾
    • 3.3.页主体
    • 3.4.页目录
    • 3.5.数据页头
  • 4.B+树在MySQL索引中的应用
    • 4.1.计算三层树高的B+树可以存放多少条记录
  • 5.索引分类
    • 5.1.主键索引
    • 5.2.普通索引
    • 5.3.唯一索引
    • 5.4.全文索引
    • 5.5.聚集索引
    • 5.6.非聚集索引
    • 5.7.索引覆盖
  • 6.使用索引
    • 6.1.自动创建
    • 6.2.手动创建
      • 6.2.1.主键索引
      • 6.2.2.唯一索引
      • 6.2.3.普通索引
    • 6.3.创建复合索引
    • 6.4.查看索引
    • 6.5.删除索引
      • 6.5.1.主键索引
      • 6.5.2.其他索引
    • 6.6.创建索引的注意事项
  • 7. explain语句
    • 7.1.type:访问类型
    • 7.2.使用explain


前言

前面我们学习了,数据库的增删改查等操作,在数据库中,用的最多的业务就是查找,在现实生活中,我们会发现有很多的关键字会被经常查到,为了可以更加高效地进行查询,我们为此引出索引


1.简介

1.1.索引是什么?

MySQL的索引是一种数据结构,它可以帮助数据库高效地查询,更新数据表中的数据。索引通过一定的规则排列数据表中的记录,使得对表的查询可以通过索引的搜索来加快速度。
MySQL索引类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据,比如汉语字典的目录(索引)页,我们可以按照笔画偏旁部首拼音等排序的目录(索引)快速查询到需要的字。

  • 笔画索引
    在这里插入图片描述

  • 偏旁部首索引
    ·

  • 拼音索引

在这里插入图片描述

1.2.为什么使用索引?

显而易见,使用索引的目的只有一个,就是要提升数据检索的效率,在应用程序的运行过程中,查询操作的频率远远高于增删改的频率。


2.索引应该使用什么数据结构?

2.1.Hash

时间复杂度是 O(1),查询速度非常快,但是MySQL并没有选择Hash做为索引的默认数据结构,主要原因是hash不支持范围查找

2.2.二叉搜索树

二叉搜索树的中序遍历是一个有序数组,但有几个问题导致它不适合用作索引的数据结构

  1. 最坏情况下时间复杂度为O(N),退化成了单边树
  2. 节点个数过多无法保证树高
    AVL和红黑树,虽然是平衡或者近似平衡,但是毕竟是二叉结构
    在检索数据时,每次访问某个节点的子节点时都会发生一次磁盘IO,而在整个数据库系统中,IO是性能的瓶颈,减少IO次数可以有效的推升性能。
    在这里插入图片描述
    在这里插入图片描述

2.3.N叉树

为了解决树高的问题,可以使用N叉树:
在这里插入图片描述

通过观察,相同数据量的情况下,N叉树的树高可以得到有效的控制,也就意味这在相同数据量的情况下可以减少IO的次数,从而提升效率。但是MySQL认为N叉树做为索引的数据结构还不够好。

2.4.B+树

2.4.1. 简介

B+树是⼀种经常用于数据库和文件系统等场合的平衡查找树,MySQL索引采用的数据结构,以4阶B+树为例,如下图所示:
在这里插入图片描述

2.4.2. B+树的特点

  1. 能够保持数据稳定有序,插入与修改有效为稳定的时间复杂度
  2. 非叶子节点尽有索引作用,不存储数据,所以叶子节点保真实数据
  3. 所有叶子节点构成一个有序链表,可以按照key排序的次序依次遍历全部数据

2.4.3. B+树和B树的对比

  1. 叶子节点中的数据是连续的,且相互链接,便于区间查找和搜索
  2. 非叶子节点的值都包含在叶子节点中
  3. 对于B+树而言,在相同树高的情况下,查找任意元素的时间复杂度都一样,性能均衡

索引在整个数据检索的过程中是如何工作的,要从MySQL存储结构说起

3.Mysql中的页

3.1.为什么要使用页

.ibd 文件中最重要的结构体就是Page(页),页是内存与磁盘交互的最小单元,默认大小为16KB,每次内存与磁盘的交互至少读取一页,所以在磁盘中每个页内部的地址都是连续的,之所以这样做,是因为在使用数据的过程中,根据局部性原理,将来要使用的数据大概率与当前访问的数据在空间上是临近的,所以依次从磁盘中读取一页的数据放入内存中,当下次查询的数据还在这个页中就可以从内存中直接读取,从而减少磁盘IO提高性能。

局部性原理:
是指程序在执行时呈现出局部性规律,在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储的存储空间也局限于某个内存区域,局部性通常有两种形式:时间局部性和空间局部性
时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期他很可能还会被再次访问
空间局部性(Spatial Locality):将来要用到的信息大概率与正在使用的信息在空间地址上是临近的

  • 每一页中即使没有数据也会使用16KB的存储空间,同时与索引的B+树种的节点对应。查看页的大小,可以通过系统变量innodb_page_size查看。
    在这里插入图片描述
  • 在MySQL中有很多种不同类型的页,最常用的就是用来存储数据和索引的索引页也叫做"数据页",但不论哪种类型的页都会包含页头(File Header)页尾(File Trailer),页的主体信息使用**数据"行"**进行填充,数据页的基本结果如下图所示:

在这里插入图片描述

3.2.页文件头和页文件尾

页文件头和页文件尾中包含的信息,如下图所示:
在这里插入图片描述
这里我们只关注,上一页页号和下一页页号,通过这两个属性可以把页与页之间链接起来,形成⼀个双向链表

3.3.页主体

页主体部分是保存真实数据的主要区域,每当创建一个新页,都会自动分配两个行,一个是页内最小行Infimun,另外一个是页内最大行Supremun,这两个行并不存储任何真实信息,而是作为数据行链表的头和尾,第一个数据行有一个记录下一行的地址偏移量的区域next_record 将页内所有数据行组成一个单向链表,此时新页的结构如下所示:
在这里插入图片描述

当向一个新页插入数据时,将Infimun连接第一个数据行,最后一个真实数据行连接Supremun,这样数据行就构建成了一个单向链表,更多的行数据插入后,会按照主键从小到大的顺序进行连接,如下图所示:
在这里插入图片描述

3.4.页目录

  • 当按主键或索引查找某条数据时,最直接简单的方法就是从头行Infimun开始,沿着链表顺序逐个比对查找,但一页有16kb,通常会存在数百行数据,每次都要遍历数百行,无法满足高效查询,为了提高效率,InnoDB采用二分查找来解决查询效率的问题。
  • 具体实现方式是,在每一个页中加入一个叫做页目录(Page Directory) 的结构,将页内包括头行、尾行在内的所有行进行分组,约定头行单独为一组,其他每个组最多8条数据,同时把每个组最后一行在页中的地址,按主键从小到大的顺序记录在页目录中,页目录中的每一个位置称为一个,每个槽都对应了一个分组,一旦分组中的数据行超过分组的上线8个时,就会分裂出一个新的分组。
  • 后续在查询某行时,就可以通过二分查找,先找到对应的槽,然后在槽内最多8个数据行中进行遍历即可,从而大幅度提高了查询效率,这时一恶搞页的核心结构就完成了。
  • 例如要查询主键为6的行,先比对槽中记录的主键值,定位到最后一个槽2,再从最后一个槽中的第一条记录遍历,第二条记录就是我们要查询的目标行。

在这里插入图片描述

3.5.数据页头

数据页头记录了当前页保存数据相关的信息,如下图所示:
在这里插入图片描述


4.B+树在MySQL索引中的应用

非叶子节点在保存索引数据,叶子结点保存真实数据
在这里插入图片描述
以查找id为5的记录,完整的检索过程如下:

  1. 首先判断B+树的根节点中的索引记录,此时 5<7,应该访问左孩子节点,找到索引2
  2. 在索引页2中判断id的大小,找到与5相等的记录,然后加载对应的数据页

以上的IO过程,加载索引页1 - - - > 加载索引页2 - - -> 加载数据页3

4.1.计算三层树高的B+树可以存放多少条记录

  • 假设一条用户数据大小为1kb,在忽略数据页中数据页自身属性空间占用的情况下,一页可以存16条数据
  • 索引页一条数据的大小为,主键用BIGINT类型占8byte,下一页地址6byte,一共是14byte,一个索引页可以保存 16*1024/14 = 1170 条索引记录
  • 如果只有三层树高的情况下,综合只保存索引的根节点和二级节点的索引页以及保存真实数据的数据页,那么一共可以保存1170117016 = 21,902,400 条记录,也就是说在两千多万条数据表中,可以通过三次IO就完成了数据的检索

5.索引分类

5.1.主键索引

  • 当在一个表上定义一个主键PRIMARY KEY时,自动创建索引,索引的值是主键列的值,InnoDB使用它作为聚集索引
  • 推荐为每个表定义一个主键,如果没有逻辑上唯一且非空的列集可以使用主键,则添加一个自排列。

5.2.普通索引

  • 最基本的索引类型,没有唯一性的原则
  • 可能为多列创建组合索引,称为复合索引。

5.3.唯一索引

  • 当在一个表上定义一个唯一键UNIQUE时,自动创建唯一索引
  • 与普通索引类似,但区别在于唯一索引的列不允许有重复值。

5.4.全文索引

  • 基于文本列(CHAR,WARCHAR或TEXT列)上创建,以加快对这些列中包含的数据查询和DML操作
  • 用于全文搜索,仅MylSAM和InnoDB引擎支持

5.5.聚集索引

  • 与主键索引是同义词
  • 如果没有为表定义PRIMARY KEY,InnoDB使用第一个UNIQUENOT NULL的列作为聚集索引。
  • 如果表中没有PRIMARY KEY或合适的UNIQUE索引,InnoDB会为新插入的行生成一个行号并用6字节的ROW_ID字段记录,ROW_ID单调递增,并使用ROW_ID做为索引

5.6.非聚集索引

  • 聚集索引以外的索引称为非聚集索引或二级索引
  • 二级索引中的每条记录都包含该行的主键列,以及二级索引指定的列
  • InnoDB使用这个主键值来搜索聚集索引中的行,这个过程称为回表查询

5.7.索引覆盖

当一个select语句使用了普通索引且查询列表中的列刚好是创建普通索引时的所有或部分列,这时就可以直接返回数据,而不用回表查询,这样的现象称为索引覆盖


6.使用索引

6.1.自动创建

当我们为一张表加主键约束(Primary Key),外键约束(Foreign Key),唯一约束(Unique)时,MySQL会为对应的列自动创建一个索引
如果表不指定任何约束时,MySQL会自动为每一列生成一个索引并用ROW_ID进行标识

6.2.手动创建

6.2.1.主键索引

方法一:
创建表时指定主键并查看表结构

create table t_pk1(
id bigint primary key auto_increment,
name varchar(50)
);
desc t_pk1;

在这里插入图片描述
查看索引内容

show index from t_pk1;

在这里插入图片描述
方法二:
创建表时单独指定主键列

create table t_pk2(
id bigint auto_increment,
name varchar(50),
primary key (id)
);

在这里插入图片描述
方法三:
修改表中的列为主键索引

create table t_pk3(
id bigint,
name varchar(50)
);
-- 修改表中的id列为主键索引
alter table t_pk3 add primary key (id);
alter table t_pk3 modify id bigint auto_increment;

在这里插入图片描述

6.2.2.唯一索引

唯一约束跟上面的操作流程都一样,下面只写部分代码,大家可以按照上面的流程进行操作。

# ⽅式一,创建表时创建唯⼀键
create table t_test_uk (
id bigint primary key auto_increment,
name varchar(20) unique
);
# ⽅式二,创建表时单独指定唯⼀列
create table t_test_uk1 (
id bigint primary key auto_increment,
name varchar(20),
unique (name)
);
# ⽅式三,修改表中的列为唯⼀索引
create table t_test_uk2 (
id bigint primary key auto_increment,
name varchar(20)
);
alter table t_test_uk2 add unique (name);

6.2.3.普通索引

方法一:创建表的时候创建普通索引

create table t_index1(
	id bigint primary key auto_increment,
	name varchar(50) unique,
	sno varchar(20),
	index(sno)
);

在这里插入图片描述
方法二:修改表中的列为普通索引

create table t_index2(
  id bigint primary key auto_increment,
  name varchar(20) unique,
  sno varchar(20)
);
alter table t_index2 add index(sno);

在这里插入图片描述
方法三:单独创建索引并指定索引名

create table t_index3(
	id bigint primary key auto_increment;
	name varchar(20),
	sno varchar(20)
);
-- 为name列建立索引,不指定索引名时失效,必须要指定名字
create index idx_t_index3_sno on t_index3(sno);

在这里插入图片描述
删除索引

alter table t_index3 drop index idx_t_index3_sno;

在这里插入图片描述

6.3.创建复合索引

创建语法与创建普通索引相同,只不过制定多个列,列与列之间用逗号隔开
方法一:创建表时指定索引列

create table t_index4(
id bigint primary key auto_increment,
name varchar(50),
sno varchar(20),
class_id bigint,
index(sno,name)
);

在这里插入图片描述

方法二:修改表中的列为复合索引

create table t_index5(
	id bigint primary key auto_increment,
	name varchar(50),
	sno varchar(50),
	class_id bigint
);
alter table t_index5 add index(sno,name);

方法三:单独创建索引并指定索引名

create table t_index6(
	id bigint primary key auto_increment,
	name varchar(20),
	sno varchar(20),
	class_id bigint
);
create index idx_t_index6_sno_name on t_index6 (sno,name);

在这里插入图片描述

6.4.查看索引

方法一:

show keys from 表名\G;

在这里插入图片描述

方法二:

show index from 表名;

在这里插入图片描述

方法三:

desc 表名;

在这里插入图片描述

6.5.删除索引

6.5.1.主键索引

如果直接删除自增列的主键索引,会发生下面的状态

alter table t_index6 drop primary key;

在这里插入图片描述
如果不出现错误呢?
先把id的自增性删除掉,再删除主键索引

alter table t_index6 modify id bigint;

在这里插入图片描述

alter table t_index6 drop primary key;

在这里插入图片描述

6.5.2.其他索引

alter table 表名 drop index 索引列名;

在这里插入图片描述

6.6.创建索引的注意事项

  • 索引应该创建在高频查询的列上
  • 索引需要占用额外的存储空间
  • 对表进行插入、更新和删除操作,同时也会修索引,可能会影响性能
  • 创建过多或者不合理的索引会导致性能下降,需要谨慎选择和规划索引

7. explain语句

explain 语句就是为了查看自己写的SQL语句是否使用了索引

7.1.type:访问类型

类型说明
ALL扫描全表
index扫描全部索引树
range扫描部分索引,索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between,<,>等的查询
ref使用非唯一索引或非唯一索引前缀进行的查找,不是主键或不是唯一索引
eq_ref唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
const单表中最多有一个匹配行,查询起来非常迅速,例如根据主键或唯一索引查询。
system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL不用访问表或者索引,直接就能得到结果
从上面到下面,其中性能由低到高

7.2.使用explain

首先先在student表中添加一个复合主键,然后在再查一下索引结构

create index idx_student_sn_name on student(sn,name);

在这里插入图片描述

show index from student;

在这里插入图片描述

  1. 不加条件,查询所有
explain select * from student;

在这里插入图片描述

  1. 使用主键
explain select * from student where student_id = 1;

在这里插入图片描述

  1. 子查询中使用索引
explain select * from student where student_id =(select studnet_id from student where student_id = 1);

在这里插入图片描述

  1. 使用普通索引
explain select * from student where sn = '09982';

在这里插入图片描述

  1. 使用复合索引
explain select * from student where sn = '09982' and name = '黑旋风李逵';

在这里插入图片描述
现在我们删除sn这个唯一索引

alter table student drop index sn;

在这里插入图片描述

explain select sn,name from student where sn ='09982' and name = '黑旋风李逵';

在这里插入图片描述
可能在写代码的时候会写这样的

explain select sn from student where name ='黑旋风李逵';

Extra:执行情况的说明和描述,包含不适合在其他列中显示但非常重要的额外消息。
Using index 和 Using where:

  1. Using index:表示使用索引,如果只有 Using index,说明没有查询到数据表,只用索引表就完成了这个查询,这个叫做覆盖索引
  2. Using where:表示条件查询,如果不读取表的所有数据,或不是仅仅通过索引就可以获取皆可以获取所有需要的数据,则会出现 Using index
    在这里插入图片描述

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

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

相关文章

【Linux】解锁线程基本概念和线程控制,步入多线程学习的大门

目录 1、线程初识 1.1线程的概念 1.2.关于线程和进程的进一步理解 1.3.线程的设计理念 1.4.进程vs线程&#xff08;图解&#xff09; 1.5地址空间的第四谈 2.线程的控制&#xff1a; 2.1.关于线程控制的前置知识 2.2创建线程的系统调用&#xff1a; 这个几号手册具体…

JavaScript | 定时器(setInterval和clearInterval)的使用

效果图如下&#xff1a; 当用户第一次看到这个页面时&#xff0c;按钮是不可点击的&#xff0c;并显示一个5秒的倒计时。倒计时结束后&#xff0c;按钮变为可点击状态&#xff0c;并显示“同意协议”。这样做的目的是确保用户有足够的时间阅读用户协议。 <!DOCTYPE html>…

机器学习:知识蒸馏(Knowledge Distillation,KD)

知识蒸馏&#xff08;Knowledge Distillation&#xff0c;KD&#xff09;作为深度学习领域中的一种模型压缩技术&#xff0c;主要用于将大规模、复杂的神经网络模型&#xff08;即教师模型&#xff09;压缩为较小的、轻量化的模型&#xff08;即学生模型&#xff09;。在实际应…

Vue(3) 组件

文章目录 对组件的理解单文件组件非单文件组件基本使用几个注意点组件的嵌套VueComponent构造函数一个重要的内置关系 组件的自定义事件全局事件总线安装全局事件总线使用事件总线解绑事件消息订阅与发布简介使用步骤范例 $nextTick插槽1.默认插槽2.具名插槽作用域插槽 对组件的…

[linux 驱动]网络设备驱动详解

目录 1 描述 2 结构体 2.1 net_device 2.2 sk_buff 2.3 net_device_ops 2.4 ethtool_ops 3 相关函数 3.1 网络协议接口层 3.1.1 dev_queue_xmit 3.1.2 netif_rx 3.1.3 alloc_skb 3.1.4 kfree_skb 3.1.5 skb_put 3.1.6 skb_push 3.1.7 skb_reserve 3.2 网络设备驱…

使用OpenCV实现基于EigenFaces的人脸识别

引言 人脸识别技术近年来得到了飞速的发展&#xff0c;它被广泛应用于安全监控、门禁系统、智能设备等领域。其中&#xff0c;基于特征脸&#xff08;EigenFaces&#xff09;的方法是最早期且较为经典的人脸识别算法之一。本文将介绍如何使用Python和OpenCV库实现一个简单的人…

AI大模型面经——以医疗领域为例,整理RAG基础与实际应用中的痛点

前言 谈到大模型在各垂直领域中的应用&#xff0c;一定离不开RAG&#xff0c;本系列开始分享一些RAG相关使用经验&#xff0c;可以帮助大家在效果不理想的时候找到方向排查或者优化。 本系列以医疗领域为例&#xff0c;用面试题的形式讲解RAG相关知识&#xff0c;开始RAG系列…

Spring与Spring Boot之间的区别

Spring和Spring Boot是用于开发Java企业应用的两个主流框架。虽然它们都属于Spring生态系统的一部分&#xff0c;但是它们各自有不同的使用场景和特点。 在本文中&#xff0c;我们将探讨Spring与Spring Boot之间的差异&#xff0c;针对他们之间特性的差异&#xff0c;做一个详…

windows10系统-在线设置账户有效期

.a.打开微软官网 点击右上角的登录按钮 .b.输入自己idea账户名&#xff0c;然后点击下一步 .c.使用邮箱接收验证码 输入验证码->登录 .d.点击右上角的个人账户->我的 Microsoft 账户 .e.点击更改密码即可 .f.修改完密码之后&#xff0c;点击保存即可。 微软的在线账户和…

XGBoost回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出

回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出 目录 回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 XGBoost的全称是eXtreme Gradient Boosting,它是经过优化的分布式梯度提升库,旨在高效、…

【python学习】1-1 python软件安装

1。搜索python官网&#xff0c;点击下载进行下载安装包。 2.双击.exe文件&#xff0c;如图步骤 3.winR输入cmd&#xff0c;在弹出黑框中输入python显示如图安装好。

linux线程 | 同步与互斥(上)

前言&#xff1a;本节内容主要是线程的同步与互斥。 本篇文章的主要内容都在讲解互斥的相关以及周边的知识。大体的讲解思路是通过数据不一致问题引出锁。 然后谈锁的使用以及申请锁释放锁的原子性问题。 那么&#xff0c; 废话不多说&#xff0c; 现在开始我们的学习吧&#x…

基于element-ui的upload组件与阿里云oss对象存储的文件上传(采用服务端签名后直传的方式)

服务端签名后直传图解 步骤 1 开通阿里云OSS对象存储服务&#xff0c;创建新的Bucket 2 创建子账户获取密钥 创建用户 添加权限 后端 1 新建一个第三方服务的模块 third-party pom文件 <?xml version"1.0" encoding"UTF-8"?> <project x…

【工程测试技术】第4章 常用传感器分类,机械式,电阻式,电容式,电感式,光电式传感器

上理考研周导师的哔哩哔哩频道 我在频道里讲课哦 目录 4.1 常用传感器分类 4.2 机械式传感器及仪器 4.3 电阻式、电容式与电感式传感器 1.变阻器式传感器 2.电阻应变式传感器 3.固态压阻式传感器 4.典型动态电阻应变仪 4.3.2 电容式传感器 1.变换原理 2.测量电路 …

ScriptableObject基本使用

使用方法 自定义类继承ScriptableObject 可以在类内部增加数据或者数据类&#xff0c;一般用于配置 注意事项 给继承ScriptableObject的类增加CreateAssetMenu特性。 CreateAssetMenu一般默认三个参数 第一个参数是父目录 第二个参数是父目录的子选项 第三个参数是可以…

[瑞吉外卖]-05菜品模块

文件上传下载 介绍 文件上传也称为upload&#xff0c;是指将本地图片、视频、音频等文件上传到服务器上, 可以供其他用户浏览或下载 前端组件库提供了上传组件&#xff0c;但是底层原理还是基于form表单的文件上传。 服务端要接收客户端上传的文件&#xff0c;通常都会使用Ap…

QT--QPushButton设置文本和图标、使能禁能、信号演示

按钮除了可以设置显示文本之外&#xff0c;还可以设置图标 文本 可以获取和设置按钮上显示的文本 // 获取和设置按钮的文本 QString text() const void setText(const QString &text)该属性&#xff0c;既可以在 Qt 设计师右侧的属性窗口中修改&#xff0c;也可以在代码…

深度学习调参技巧总结

文章目录 深度学习调参技巧总结1.寻找合适的学习率2.优化算法选择3.模型对不同超参数的敏感性4.训练技巧参考 深度学习调参技巧总结 1.寻找合适的学习率 学习率&#xff08;Learning Rate, LR&#xff09;是机器学习模型训练中极其重要的超参数。它直接影响模型的收敛速度和最…

数据结构——排序(2)

数据结构——排序(2) 文章目录 数据结构——排序(2)前言&#xff1a;1.快速排序&#xff08;非递归版本&#xff09;基本步骤&#xff1a;代码实现 2.归并排序算法思想&#xff1a;核心步骤&#xff1a;代码实现&#xff1a;特征总结&#xff1a; 3.计数排序&#xff08;非比较…

【深度学习系统】Lecture 2 - ML Refresher / Softmax Regression

一、问题的理解方式 首先&#xff0c;什么是数据驱动的编程&#xff1f;面对经典的MNIST数据集识别任务&#xff0c;传统的编程思维和数据驱动的编程思维有何不同&#xff1f; 传统编程思维&#xff1a; 通常从明确的问题定义和具体的算法开始。对于 MNIST 数据集识别任务&a…