MySQL原理(三):索引

news2024/11/15 11:31:39

前言

上一篇介绍了 MySQL 的逻辑架构和执行过程,这一篇将介绍索引相关的内容。

索引是用额外的数据结构,来实现快速检索目标数据的。就像字典当中的目录一样,用额外的空间来存储部分内容,从而加快检索速度。

MySQL 的逻辑架构分为 Server 层和存储引擎层,其中索引和数据就位于存储引擎中,而不同的存储引擎可能有不同的实现索引的方式,比如常见的 InnoDB 和 MyISAM 使用的都是 B+Tree,但是实现方式不同。

按照不同的分类方式,索引可以分为以下几类:

  • 按「数据结构」分类:B+ 树索引、B 树索引、Hash 索引等。
  • 按「物理存储」分类:聚簇索引(主键索引)、非聚簇索引(二级索引)。
  • 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引、全文索引、空间索引等。
  • 按「字段个数」分类:单列索引、联合索引。

B+树索引

B+ 树是一种多叉平衡搜索树,叶子节点才存放数据,非叶子节点只存放索引,而且每个节点里的数据是按主键顺序存放的。每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都指向下一个叶子节点,形成一个链表。所有节点按照索引键大小排序,构成一个双向链表,便于范围查询。

在这里插入图片描述

虽然,InnoDB 和 MyISAM 都支持 B+ 树索引,但是它们数据的存储结构实现方式不同:

  • InnoDB 存储引擎:B+ 树索引的叶子节点保存数据本身(数据页);
  • MyISAM 存储引擎:B+ 树索引的叶子节点保存数据的物理地址;

由于物理空间地址是混乱无序的,MyISAM 只能先取数据,再排序;而 InnoDB 的物理存放顺序和索引顺序一致。

后续如果没有额外说明,则默认说的都是 InnoDB 中的 B+ 树索引的实现。

InnoDB 里的 B+ 树中的每个节点都是一个数据页

B+树-数据页 ![在这里插入图片描述](https://img-blog.csdnimg.cn/9a0e1016ce3b47bb927fa27f9acf3c2a.png#pic_center)

B树和B+树

B 树又名平衡多路查找树,B 树中所有结点的孩子个数的最大值称为 B 树的阶,通常用 m 表示。

在这里插入图片描述

B 树和 B+ 树的区别在于,B 树的每个节点都存储了 key 和 data,而 B+ 树的 data 只存储在叶子节点上,这样单个节点可以存更多的索引键,树的高低就越小,查询时磁盘 IO 的次数就越小。且 B 树没有冗余节点,而 B+ 树有冗余节点。

B+ 树的冗余节点:不仅在叶节点中保存了所有的键,且部分键在非叶节点中也存在。

具体区别:

1、单点查询

B 树的查询效率可能更高,但波动较大;B+ 树相对更矮胖,查询底层节点的 I/O 次数更少。

B+ 树的非叶子节点不存放实际的记录数据,仅存放索引值,因此数据量相同的情况下,B+ 树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O 次数会更少。

2、范围查询

B 树的范围查询相当于树的遍历,效率很低;B+ 树的叶子节点间还有双链表连接,利于范围查询。

3、插入删除效率

B 树没有冗余节点,插入和删除都需要涉及树的变形;B+ 树存在冗余节点,插入和删除时不需要涉及树的变形,效率更高。

为什么选择 B+ 树而不是红黑树(或其他平衡二叉搜索树)?

红黑树(或其他平衡二叉搜索树)每个节点只能存储一个数据,所以在数据量大的情况下,树高很大,会导致多次磁盘 IO。

按物理存储分类

聚簇索引

Clustered Index,又称主键索引,叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+ 树的叶子节点里。

因为表的数据都是存放在聚簇索引的叶子节点里,所以 InnoDB 存储引擎一定会为表创建一个聚簇索引,且由于数据在物理上只会保存一份,所以聚簇索引只能有一个。

在创建表时,InnoDB 存储引擎会根据不同的场景选择不同的列作为索引:

  1. 如果有主键,默认会使用主键作为聚簇索引的索引键;
  2. 如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键;
  3. 在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键;

当执行一条查询语句,比如使用主键索引查询 id 号为 5 的商品时,B+ 树会自顶向下逐层进行查找,查询过程是这样的:

  1. 将 5 与根节点的索引数据(1,10,20)比较,因为 5 在 1 和 10 之间,根据搜索逻辑,会找到第二层的索引数据(1,4,7);
  2. 在第二层的索引数据(1,4,7)中进行查找,因为 5 在 4 和 7 之间,所以找到第三层的索引数据(4,5,6);
  3. 在叶子节点的索引数据(4,5,6)中进行查找,然后找到了索引值为 5 的行数据,完成查找。

在这里插入图片描述

数据库的索引和数据都是存储在硬盘的,我们可以把读取一个节点当作一次磁盘 I/O 操作。那么上面的整个查询过程一共经历了 3 个节点,也就是进行了 3 次 I/O 操作。

以一个整数字段索引为例,每个节点大约能存储 1200 条索引数据。当这棵树高是 4 的时候,就可以存 1200^3≈17 亿条记录。所以在一个 10 亿行的表上根据一个整数字段的索引查找一个值最多只需要访问 3 次磁盘。

通常 B+ 树存储千万级的数据只需要 3-4 层高度就可以满足,这意味着从千万级的表查询目标数据最多需要 2-3 次磁盘 I/O。

非聚簇索引

Secondary Index,又称二级索引、辅助索引,主键索引的 B+ 树和二级索引的 B+ 树区别如下:

  • 主键索引的 B+ 树的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+ 树的叶子节点里;
  • 二级索引的 B+ 树的叶子节点存放的是主键值,而不是实际数据。

通过二级索引查询数据的过程:

这里将商品编号字段设置为二级索引,那么二级索引的 B+ 树如下图,其中非叶子的 key 值是 product_no(橙色部分),叶子节点存储的数据是主键值(绿色部分)。

如果用二级索引查询商品,会先检二级索引中的 B+ 树的索引值,检索过程与上文介绍的一致,找到对应的叶子节点获取主键值,然后再通过主键索引中的 B+ 树查询到对应的叶子节点,获取整行数据。这个过程叫「回表」,也就是说要查两个 B+ 树才能查到数据。如下图:

在这里插入图片描述

在索引树上,每次只能根据一个主键 id 查到一行数据,所以回表是一行行搜索主键索引的。

按字段特性分类

主键索引

建立在主键字段上的索引,通常在创建表的时候一起创建,一张表最多只有一个主键索引,索引的值唯一且不能为空值

唯一索引

建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,索引列的值必须唯一,允许存在多个空值。

由于索引的唯一性,查询性能是最好的。但是在更新数据时,需要额外的查询来保证索引的唯一性,所以写性能会偏低。

由于每次更新前都需要通过查询来判断唯一性,所以唯一索引没有使用 change buffer,所以写性能会低很多。

普通索引

建立在普通字段上的索引,既不要求字段为主键,也不要求字段为 UNIQUE。

前缀索引

前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。

使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。但是由于前缀索引没有存储一个字段的完整值,所以无法完成排序分组等工作。

全文索引

MySQL5.6 之前,只有 MyISAM 支持,MySQL 5.6 及以后的版本,InnoDB 也支持全文索引。只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。

全文索引在做模糊查询的时候性能很高,但是由于会对字段做分词处理,分词结果也会存储在全文索引中,所以会占用很大的空间。

修改字段值后,需要时间分词,所以不会立刻更新全文索引,如果对实时性要求高,则需要手动更新。

一般可以使用 ElasticSearch、Solr、MeiliSearch 等搜索引擎来代替全文索引。

联合索引

联合索引的非叶子节点会按顺序用联合索引的字段作为键值,使用联合索引时,会按照最左匹配原则,也就是按照最左优先的方式进行索引的匹配。

联合索引范围查询

联合索引的最左匹配原则会一直向右匹配直到遇到「范围查询」就会停止匹配。也就是范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引

select * from t_table where a > 1 and b = 2 在符合 a > 1 条件的二级索引记录的范围里,b 字段的值是无序的,所以联合索引的 b 字段并没有使用到索引。

select * from t_table where a >= 1 and b = 2SELECT * FROM t_table WHERE a BETWEEN 2 AND 8 AND b = 2 都有使用到联合索引。(在边界值时)

联合索引的最左匹配原则,在遇到范围查询(如 >、<)的时候,就会停止匹配,也就是范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引。注意,对于 >=、<=、BETWEEN、like 前缀匹配的范围查询,并不会停止匹配。

索引下推

ICP,Index Condition Pushdown。

对于联合索引(a, b),在执行 select * from table where a > 1 and b = 2 语句的时候,只有 a 字段能用到索引。

  • 在 MySQL5.6 之前,只能从一个个回表,到「主键索引」上找出数据行,再对比 b 字段值。
  • 而 MySQL5.6 引入索引下推优化后,可以在联合索引遍历过程中,对联合索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数

覆盖索引

Covering Index,在使用二级索引字段作为条件查询的时候,如果从二级索引中就能查找到需要的数据,而不必再次回表查询,这样就叫做覆盖索引。

示例:

ALTER TABLE `t_user` ADD INDEX `idx1`(`name`,`id`) USING BTREE;
// name 字段为二级索引
select id from t_user where name="木木";

MRR

Multi-Range Read Optimization,是在 MySQL5.6 中引入的性能优化措施,默认开启。通过把「随机磁盘读」转化为「顺序磁盘读」,从而提高了索引查询的性能。

随机磁盘读:在磁盘上随机读取数据,磁盘读取头需要不断移动到不同位置,导致产生大量的磁盘寻道时间,从而降低读取性能。

顺序磁盘读:按照顺序读取数据,磁盘读取头在读取完一个数据块后直接移动到下一个数据块进行读取,读取性能高。

示例:

select * from user where no > 10

如果随着二级索引 no 的值递增顺序查询的话,id 的值就变成随机的,那么回表时就会出现随机磁盘访问,性能相对较差。

因为大多数的数据都是按照主键递增顺序插入得到的,所以我们可以认为,如果按照主键递增顺序查询的话,对磁盘的读比较接近顺序读,能够提升读性能。

所以就有了 MRR 优化:

  1. 根据二级索引 no,定位到满足条件的记录,将 id 值放入 read_rnd_buffer 中;
  2. 将 read_rnd_buffer 中的 id 进行递增排序;
  3. 排序后的 id 数组,依次到主键索引中查记录,并作为结果返回。

索引跳跃式扫描

Index Skip Scan,是 MySQL8.0 引入的优化机制。当没有使用到联合索引的第一个字段且后续索引字段都使用到时,可能会触发索引跳跃式扫描,会自动对联合索引中的第一个字段的值去重,然后基于去重后的值全部拼接起来查询

// 有联合索引(A,B,C),执行如下SQL
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx`;
// 原本不符合最左前缀原则,不能使用联合索引,但是如果使用了索引跳跃式扫描,则原本的SQL语句会被重构为以下形式:
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx`
UNION ALL
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx` AND A = "aaa"
......
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx` AND A = "zzz";

但是跳跃扫描机制也有很多限制,比如多表联查时无法触发、分组操作时无法触发、使用了 DISTINCT 去重无法触发等。

且只有在唯一性较差的情况下,才能发挥出不错的效果;否则相当于走一次全表扫描。不过最后还是由优化器决定是否使用该策略。

执行计划

使用 Explain 工具可以模拟优化器执行 SQL 查询语句,经常用于分析查询语句是否正确使用索引以及排查性能瓶颈。Explain 只能解释 select 语句。

示例:

EXPLAIN SELECT * FROM `zz_users`;
+----+-------------+----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | zz_users | ALL  | NULL          | NULL | NULL    | NULL |    3 |       |
+----+-------------+----------+------+---------------+------+---------+------+------+-------+

参数

  • id:执行的顺序;
  • select_type:查询类型;
  • partitions:分区信息,非分区表为 null;
  • type:数据扫描类型;
  • possible_keys:可能用到的索引;
  • key:实际用的索引,如果这一项为 NULL,说明没有使用索引;
  • key_len:索引的长度;
  • ref:连接查询的连接条件;
  • rows:扫描的数据行数;
  • extra:其他信息,有几十种不同的值;
select_type
  • simple:表示不需要 union 操作或者不包含子查询的简单查询。
  • primary:表示最外层查询。
  • subquery:子查询中的第一个查询。
  • derived:派生表查询,既 from 字句中的子查询。
  • union:union 操作中第二个及之后的查询。
  • dependent union:union 操作中第二个及之后的查询,并且该查询依赖于外部查询。
  • dependent subquery:子查询中的第一个查询,并且该查询依赖于外部查询。
  • materialized:物化查询。
  • uncacheable subquery:无法被缓存的子查询,对外部查询的每一行都需要重新进行查询。
  • uncacheable union:union 操作中第二个及之后的查询,并且该查询属于 uncacheable subquery。
type

type 字段就是描述了找到所需数据时使用的扫描方式是什么,常见扫描类型的执行效率从低到高的顺序为

  • All(全表扫描);
  • index(全索引扫描):对索引表进行全扫描,这样做的好处是不再需要对数据进行排序,但是开销依然很大;
  • range(索引范围扫描):一般在 where 子句中使用 < 、>、in、between 等关键词,只检索给定范围的行,属于范围查找;
  • ref(非唯一索引扫描):多表查询时,根据非唯一非空索引进行查询的情况;
  • eq_ref(唯一索引扫描):多表关联查询时,根据唯一非空索引进行查询的情况;
  • const(结果只有一条的主键或唯一索引扫描)。
  • NULL:无需访问表或者索引,比如获取一个索引列的最大最小值;

全表扫描和全索引扫描的效率很低,要尽量避免。

const 类型和 eq_ref 都使用了主键或唯一索引。const 是与常量进行比较,查询效率会更快;而 eq_ref 通常用于多表联查中。

extra
  • Using filesort :当查询语句中包含 group/order by 操作,且无法利用索引完成排序操作的时候, 这时不得不选择相应的排序算法进行,甚至可能会通过文件排序,效率是很低的,所以要避免这种问题的出现。
  • Using temporary:使了用临时表保存中间结果,MySQL 在对查询结果排序时使用临时表,常见于排序 order by 和分组查询 group by。效率低,要避免这种问题的出现。
  • Using index:所需数据只需在索引即可全部获得,不须要再到表中取数据,即使用了覆盖索引,避免了回表操作。

索引失效

主要有两种情况会导致索引失效:

  1. 优化器选择不使用索引。比如当索引扫描的行数超过表行数的 30% 时,就可能会选择放弃索引查询,转而使用全表扫描的方式,因为这样能够使用磁盘顺序 IO,查询效率更高。
  2. 索引的结构满足不了 SQL 语句。比如联合索引没有遵循最左匹配原则。这种情况是我们可以通过调整索引结构和改写 SQL 语句可以避免的,也是我们在进行索引优化时需要考虑的。

以下几种为常见的索引失效的场景:

  • 使用左模糊匹配时,即 like %xx 会造成索引失效;
  • 在查询条件中对索引列使用计算和函数操作;
  • 类型转换操作:比如对字符串字段使用整型作为查询参数(会发生隐式类型转换);
  • 联合索引没有遵循最左匹配原则(包括 group/order by);
  • order by 时,同时使用升序和降序;
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

索引优化

  1. 主键索引自增:插入记录时,都是追加数据,可以避免移动数据。也能够避免页分裂的情况发生。

  2. 覆盖索引优化:将所有需要查询的字段都建立联合索引,从而避免回表操作。

  3. 前缀索引优化:只使用某个字段中字符串的前几个字符建立索引,减小索引字段大小。

    局限性:

    1. order by 无法使用前缀索引
    2. 无法把前缀索引用作覆盖索引
  4. 索引设置非空:

    1. 索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,更加难以优化,因为可为 NULL 的列会使索引、索引统计和值比较都更复杂,比如进行索引统计时,count 会省略值为NULL 的行。
    2. NULL 值是一个没意义的值,但是它会占用物理空间,所以会带来的存储空间的问题,会导致更多的存储空间占用。因为 InnoDB 默认行存储格式 COMPACT,会用 1 字节空间存储 NULL 值列表。

    在这里插入图片描述

最后

本文介绍了 MySQL 索引相关的内容,最重要的是 InnoDB 是如何通过 B+ 树实现索引的,以及聚簇索引和非聚簇索引的在实现上的区别。在此基础上,就知道了索引是如何工作的,以及如何进行正确使用和优化,避免索引失效情况的发生。

下一节将介绍 MySQL 的事务。

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

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

相关文章

Python——PyQt5在PyCharm的配置与应用(保姆级教程)

目录 一、安装pycharm与python版本 二、升级pip与换源&#xff0c;安装PyQt5、PyQt5-tool 三、添加环境变量 四、在pycharm的外部工具里添加3个工具 4.1、添加三个插件&#xff08;重点&#xff09; 五、如何使用QtDesigner 六、如何使用pyuic5 一、安装pycharm与python版…

C语言——扫雷小游戏(递归展开版)

哈喽&#xff0c;大家好&#xff0c;上次我们已经学习了三子棋小游戏&#xff0c;今天我们来学习扫雷小游戏了。 目录 1.游戏介绍 2.函数部分 2.1菜单 2.2game()函数 2.3mian()函数 2.4初始化棋盘 2.5打印棋盘 2.6布置雷 2.7排查雷 2.8统计雷 2.9递归,展开一片区域 …

眼球追踪、HDR、VST,从代码挖掘Valve下一代VR头显

擅长爆料、挖掘线索的Brad Lynch&#xff0c;此前发布了Quest Pro等设备的线索文章引发关注。​近期&#xff0c;又公布一系列与“Valve Deckard”VR头显相关消息&#xff0c;比如支持眼球追踪、HDR、VST透视、Wi-Fi网络等等。在SteamVR 1.26.1测试版更新、Steam用户端、Gamesc…

lazada、shopee转化率低怎么办?做好这几点,让你的店铺转化率提升

如若lazada, shopee如果转化率低&#xff0c;商家需要做好以下几个方面&#xff0c;通过以下几点来提高。毕竟只有流量没有转化率&#xff0c;店铺管理不好。 1、产品类别的选择 一个好的类别本身就是一个很好的排水渠道&#xff0c;可以给我们带来大量的流量&#xff0c;高流…

数据结构与算法基础(王卓)(38):排序、全部PPT、笔记整理

首先&#xff0c;庆祝本系列完结撒花&#xff01; 对了&#xff0c;后续应该会把王卓老师所有的PPT附带笔记全部打包上传百度云 回头我把链接贴出来&#xff0c;感兴趣的朋友可以Mark一下&#xff0c;希望可以帮助到大家 如果有什么写的不对的地方&#xff0c;先给大家说声抱…

23年的软件测试前景?我卷自动化测试卷出头了,拿下22K*15薪...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 测试工程师主要干…

Linux一学就会——管道通信

管道通信 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某种事件&…

通过计算系统稳定性比较迭代次数

有一类差值结构可能有一行中的数字比其他行的都多&#xff0c;因此有天然的底部&#xff0c;很容易确定平均列的顺序。但是可能有的差值结构相同的底部不止一个&#xff0c;这次比较双底部差值结构迭代次数的顺序。 ( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入有3个节…

2023年US News最佳MBA排名出炉,申请需要哪些条件?

在出国留学的大环境下&#xff0c;MBA文凭一直都非常受欢迎&#xff0c;美国商学院是中国学生热衷的留学方向&#xff0c;而针对管理者的MBA项目也受到追捧。 US News 统计了美国130个全日制MBA的毕业生起薪&#xff0c;2023年毕业生的平均工资为 $105,684&#xff0c;Top 10 …

纽扣电池/含纽扣电池商品亚马逊美国澳洲站点合规认证要求!

纽扣电池/含纽扣电池商品亚马逊美澳站点合规认证 亚马逊美国站纽扣电池&#xff08;含纽扣电池产品&#xff09;合规要求标准&#xff1a; 16CFR1700.15部分(防毒包装标准) 16CFR1700.20部分(特殊包装的检测程序) ANSI C18.3M(便携式锂原电池的安全标准) 警示标签声明要求(…

对于零基础小白来说,转行学云计算和java哪个更好一些?求推荐

对于零基础小白来说&#xff0c;转行学云计算和java哪个更好一些&#xff1f; 云计算和Java是两个不同的技术领域&#xff0c;虽然它们都与计算机网络、分布式系统和互联网应用程序等相关&#xff0c;但它们的学习重点和应用场景也不同。虽然他们都是非常有前途的IT领域&#x…

Web3中文|比特币 BRC-20 让“闪电网络”再受热议

一位幸运的矿工在上周日晚上赚取了 6.701 枚BTC&#xff08;约 200,000 美元&#xff09;的交易费用&#xff0c;超过了当前的 6.25 BTC 的区块奖励。这一极为罕见的事件说明了与 Ordinals 协议相关的区块链活动导致了用户成本的飙升。 高昂的比特币交易费用 2022年底&#xff…

RT-DETR原理与简介(干翻YOLO的最新目标检测项目)

概述与简介 RT-DETR是一种实时目标检测模型&#xff0c;它结合了两种经典的目标检测方法&#xff1a;Transformer和DETR&#xff08;Detection Transformer&#xff09;。Transformer是一种用于序列建模的神经网络架构&#xff0c;最初是用于自然语言处理&#xff0c;但已经被证…

反射机制【Java】

文章目录 定义获得Class对象的方式反射的具体使用几个重要的类及方法反射的优缺点 在一些特定的场景中&#xff0c;我们可能会需要获取一些私有的成员变量或方法的信息&#xff0c;但直接在类外调用是无法成功获取到的&#xff0c;因此我们就需要一种机制来获取一些需要的变量或…

多媒体通信有些SCI期刊推荐? - 易智编译EaseEditing

以下是一些多媒体通信领域的SCI期刊推荐&#xff1a; IEEE Transactions on Multimedia&#xff1a; 这是IEEE计算机学会旗下的一个期刊&#xff0c;涵盖了多媒体信号的处理、编码、压缩、传输和交互等方面的研究。 ACM Transactions on Multimedia Computing, Communication…

操作系统原理 —— 七种常见的调度算法(十三)

大家都知道&#xff0c;学习这种类型的算法&#xff0c;在很多时候&#xff0c;我们只是学习它的一种思想&#xff0c;那有没有好的学习调度算法的思路呢&#xff1f; 我们可以基于一下路线&#xff0c;来学习调度算法&#xff1a; 1、算法思想2、算法规则3、这种调度算法是用…

Excel 冻结指定行 / 列

目录 假设你的表格是这样的&#xff1a; 1. 确定你要冻结的行列数 2. 计算下一个单元格的位置 3. 选中红框的单元格&#xff0c;视图 > 冻结窗格 > 冻结拆分窗格 4. 出现下面红框中的线即代表功能已经实现。 在使用 Excel 的过程中&#xff0c;经常会需要保持某一行 / 某…

【目标检测】入门教程之yolo v1理论与实战

every blog every motto: There’s only one corner of the universe you can be sure of improving, and that’s your own self. https://blog.csdn.net/weixin_39190382?spm1010.2135.3001.5343 0. 前言 目标检测入门实战教程 1. 正文 1.1 感性认识 我们想做的事&…

【shell脚本】数组

数组 一、数组1.1数组的定义方法1.2数组包括的数据类型1.3获取数组的元素1.4数组追加1.5向函数传入数组的值 二、排序算法2.1冒泡排序2.2直接选择排序2.3插入排序2.4反转排序 一、数组 1.1数组的定义方法 格式 方法一&#xff1a; 数组名&#xff08;1 2 3 4 5&#xff09;#…

Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 转载自cpolar极点云的文章&#xff1a;在Ubunt…