MySQL调优02 - SQL语句的优化

SQL语句的优化

文章目录

  • SQL语句的优化
    • 一:SQL优化的小技巧
      • 1:编写SQL时的注意点
        • 1.1:查询时尽量不要使用*
        • 1.2:连表查询时尽量不要关联太多表
        • 1.3:多表查询时一定要以小驱大
        • 1.4:like不要使用左模糊或者全模糊
        • 1.5:查询时尽量不要对字段做空值判断
        • 1.6:不要在条件查询=前对字段做任何运算
        • 1.7:!=、!<>、not in、or...要慎用
        • 1.8:必要情况下可以强制指定索引
        • 1.9:避免频繁创建、销毁临时表
        • 1.10:尽量将大事务拆分为小事务执行
        • 1.11:从业务设计层面减少大量数据返回的情况
        • 1.12:尽量避免深分页的情况出现
        • 1.13:SQL务必要写完整,不要使用缩写法
        • 1.14:基于联合索引查询时请务必确保字段的顺序性
        • 1.15:客户端的一些操作可以批量化完成
        • 1.17:明确仅返回一条数据的语句可以使用limit 1
      • 2:业内标准
        • 2.1:3秒原则和5秒原则
        • 2.2:mysql的500ms原则
    • 二:MySQL索引优化
      • 1:explain分析工具
        • 1.1:id字段
        • 1.2:select_type字段
        • 1.3:table字段
        • 1.4:partitions字段
        • 1.5:type字段
        • 1.6:possible_keys字段
        • 1.7:key字段
        • 1.8:key_len字段
        • 1.9:ref字段
        • 1.10:rows字段
        • 1.11:filtered字段
        • 1.12:extra字段
      • 2:索引优化参考项

一:SQL优化的小技巧

1:编写SQL时的注意点

1.1:查询时尽量不要使用*

除非确确实实的想要返回所有的字段,并且字段个数比较多。至于为什么不建议使用 *,有如下几点原因:

网络开销变大

当使用*时,查询时每条数据会返回所有字段值,然后这些查询出的数据会先被放到结果集中,最终查询完成后会统一返回给客户端

但线上Java程序和MySQL都是分机器部署的,所以返回数据时需要经过网络传输,而由于返回的是所有字段数据,因此网络数据包的体积就会变大

从而导致占用的网络带宽变高,影响数据传输的性能和资源开销。

但实际上可能仅需要用到其中的某几个字段值,所以写清楚字段后查询,能让网络数据包体积变小,从而减小资源消耗、提升响应速度。

分析成本变高

一条SQL在执行前都会经过分析器解析,当使用时,解析器需要先去解析出当前要查询的表上表示哪些字段,因此会额外增加解析成本。

如果明确写出了查询字段,分析器则不会有这一步解析*的开销。

内存占用变高

当查询一条数据时都会将其结果集放入到BufferPool的数据缓冲页中,如果每次用*来查询数据,查到的结果集自然会更大,占用的内存也会越大

单个结果集的数据越大,整个内存缓冲池中能存下的数据也就越少

当其他SQL操作时,在内存中找不到数据,又会去触发磁盘IO,最终导致MySQL整体性能下降。

维护性变差

正常情况下,我们都使用半ORM框架Mybatis进行开发【针对java】,而一般为了对应查询结果与实体对象的关系,通常都需要配置resultMap来声明表字段和对象属性的映射关系

如果每次使用*来查询数据,当表结构发生变更时,就算变更的字段结构在当前业务中用不到,也需要去维护已经配置好的resultMap,所以会导致维护性变差。但声明了需要的字段时,配置的resultMap和查询字段相同,因此当变更的表结构不会影响当前业务时,也无需变更当前的resultMap。

1.2:连表查询时尽量不要关联太多表

一旦关联太多的表,就会导致执行效率变慢,执行时间变长,原因如下:

  • 数据量会随表数量呈直线性增长,数据量越大检索效率越低。
  • 当关联的表数量过多时,无法控制好索引的匹配,涉及的表越多,索引不可控风险越大。

交互型业务和后台型业务

  • 交互型的业务中,关联的表数量应当控制在5张表之内

  • 后台型的业务由于不考虑用户体验感,有时候业务比较复杂,又需要关联十多张表做查询,此时可以这么干,但按照《高性能MySQL》上的推荐,最好也要控制在16~18张表之内(阿里开发规范中要求控制在3张表以内)。

1.3:多表查询时一定要以小驱大

所谓的以小驱大即是指用小的数据集去驱动大的数据集,说简单一点就是先查小表,再用小表的结果去大表中检索数据

其实在MySQL的优化器也会有驱动表的优化,当执行多表联查时,MySQL的关联算法为Nest Loop Join

该算法会依照驱动表的结果集作为循环基础数据,然后通过该结果集中一条条数据,作为过滤条件去下一个表中查询数据,最后合并结果得到最终数据集,MySQL优化器选择驱动表的逻辑如下:

  • 如果指定了连接条件,满足查询条件的小数据表作为驱动表。
  • 如果未指定连接条件,数据总行数少的表作为驱动表。

如果在做连表查询时,你不清楚具体用谁作为驱动表,哪张表去join哪张表,这时可以交给MySQL优化器自己选择

但有时候优化器不一定能够选择正确,因此写SQL时最好自己去选择驱动表,小表放前,大表放后!

1.4:like不要使用左模糊或者全模糊

如若like关键字以%号开头会导致索引失效,从而导致SQL触发全表查询,因此需要使用模糊查询时,千万要避免%xxx、%xxx%这两种情况出现

实在需要使用这两类模糊查询时,可以适当建立全文索引来代替,数据量较大时可以使用ES、Solr…这类搜索引擎来代替。

1.5:查询时尽量不要对字段做空值判断
select * from xxx where yyy is null;
select * from xxx where yyy not is null;

当出现基于字段做空值判断的情况时,会导致索引失效,因为判断null的情况不会走索引,因此切记要避免这样的情况

一般在设计字段结构的时候,请使用not null来定义字段

同时如果想为空的字段,可以设计一个0、""这类空字符代替:

  • 一方面要查询空值时可通过查询空字符的方式走索引检索
  • 另一方面也能避免MyBatis注入对象属性时触发空指针异常。
1.6:不要在条件查询=前对字段做任何运算
select * from users where user_id * 2 = 8;
select * from users where trim(user_name) = "张三";

users用户表中user_id、user_name字段上都创建了索引,但上述这类情况都不会走索引

因为MySQL优化器在生成执行计划时,发现这些=前面涉及到了逻辑运算,因此就不会继续往下走了,会将具体的运算工作留到执行时完成

也正是由于优化器没有继续往下走,因此不会为运算完成后的字段选择索引,最终导致索引失效走全表查询。

所以不要在条件查询=前对字段做任何运算

1.7:!=、!<>、not in、or…要慎用

总之,就是各种可能导致索引失效的写法要慎用,在实际过程中可以使用其他的一些语法代替,比如or可以使用union all来代替:

select user_name from zz_users where user_id=1 or user_id=2;
-- 可以替换成:
select user_name from zz_users where user_id=1
union all
select user_name from zz_users where user_id=2;
1.8:必要情况下可以强制指定索引

在表中存在多个索引时,有些复杂SQL的情况下,或者在存储过程中,必要时可强制指定某条查询语句走某个索引

因为MySQL优化器面对存储过程、复杂SQL时并没有那么智能,有时可能选择的索引并不是最好的,这时我们可以通过force index,如下:

select * from users force index(unite_index) where user_name = "张三";

这样就能够100%强制这条SQL走某个索引查询数据

🎉 这种强制指定索引的方式,一定要建立在对索引结构足够熟悉的情况下,否则效果会适得其反。

1.9:避免频繁创建、销毁临时表

临时表是一种数据缓存,对于一些常用的查询结果可以为其建立临时表,这样后续要查询时可以直接基于临时表来获取数据

MySQL默认会在内存中开辟一块临时表数据的存放空间,所以走临时表查询数据是直接基于内存的,速度会比走磁盘检索快上很多倍。

但一定要切记一点,只有对于经常查询的数据才对其建立临时表,不要盲目的去无限制创建,否则频繁的创建、销毁会对MySQL造成不小的负担。

1.10:尽量将大事务拆分为小事务执行

一个事务在执行事,如果其中包含了写操作,会先获取锁再执行,直到事务结束后MySQL才会释放锁。

而一个事务占有锁之后,会导致其他要操作相同数据的事务被阻塞

如果当一个事务比较大时,会导致一部分数据的锁定周期较长,在高并发情况下会引起大量事务出现阻塞,从而最终拖垮整个MySQL系统。

show status like ‘innodb_log_waits’;查看是否有大事务由于redo_log_buffer不足,而在等待写入日志。

大事务也会导致日志写入时出现阻塞,这种情况下会强制触发刷盘机制

大事务的日志需要阻塞到有足够的空间时,才能继续写入日志到缓冲区,这也可能会引起线上出现阻塞。

1.11:从业务设计层面减少大量数据返回的情况

如果一次性返回的数据量过于巨大时,就会引起网络阻塞、内存占用过高、资源开销过大的各类问题出现

因此如果项目中存在这类业务,一定要记住拆分掉它,比如分批返回给客户端。

分批查询的方式也被称之为增量查询,每次基于上次返回数据的界限,再一次读取一批数据返回给客户端,这也就是经典的分页场景

通过分页的思想能够提升单次查询的速度,以及避免大数据量带来的一系列后患问题。

1.12:尽量避免深分页的情况出现

分页虽然比较好,但也依旧存在问题,也就是深分页问题,如下:

select xx,xx,xx from yyy limit 100000,10; 

上述语句在MySQL的实际执行过程中,会先查询出100010条数据,然后丢弃前面的10W条数据,将最后10条数据返回,这个过程无异极其浪费资源。

对于深分页,有下面两种方式解决

  • 如果查询出的结果集,存在递增且连续的字段,可以基于有序字段来进一步做筛选后再获取分页数据
select xx,xx,xx from yyy where 有序字段 >= nnn limit 10; -- 例如
-- 第一页
select xx,xx,xx from yyy where 有序字段 >= 1 limit 10; 
-- 第二页
select xx,xx,xx from yyy where 有序字段 >= 11 limit 10; 
-- 第N页.....-- 第10000页
select xx,xx,xx from yyy where 有序字段 >= 100001 limit 10; 
  • 在业务上限制深分页的情况,以百度为例

在这里插入图片描述
一般用户最多看前面30页,如果还未找到他需要的内容,基本上就会换个更精准的关键词重新搜索。

如果业务必须要求展现所有分页数据,此时又不存在递增的连续字段咋办?

  • 要么选择之前哪种很慢的分页方式
  • 要么就直接抛弃所有!每次随机十条数据出来给用户,如果不想重复的话,每次新的分页时,再对随机过的数据加个标识即可。
1.13:SQL务必要写完整,不要使用缩写法

在写的时候为了图简单,都会将一些能简写的SQL就简写,但其实这种做法也略微有些问题

因为隐式的这种写法,在MySQL底层都需要做一次转换,将其转换为完整的写法

因此简写的SQL会比完整的SQL多一步转化过程,如果你考虑极致程度的优化,也切记将SQL写成完整的语法。

1.14:基于联合索引查询时请务必确保字段的顺序性

最左前缀原则,不再赘述

虽然8.0版本中推出索引跳跃扫描机制,但会存在较大的开销,同时还有很强的局限性,所以最好在写SQL时,依旧遵循索引的最左前缀原则撰写。

1.15:客户端的一些操作可以批量化完成

批量新增某些数据、批量修改某些数据的状态…,这类需求在一个项目中也比较常见,一般的做法如下:

for (xxObject obj : xxObjs) {xxDao.insert(obj);
}/*** xxDao.insert(obj)对应的SQL如下:* insert into tb_xxx values(......);
**/

这种情况确实可以实现批量插入的效果,但是每次都需要往MySQL发送SQL语句,会带来额外的网络开销以及耗时,因此上述实现可以更改为如下:

xxDao.insertBatch(xxObjs);/*** xxDao.insertBatch(xxObjs)对应的SQL如下:* insert into tb_xxx values(......),(......),(......),(......),.....;
**/

这样会组合成一条SQL发送给MySQL执行,能够在很大程度上节省网络资源的开销,提升批量操作的执行效率。

🎉 这样的方式同样适用于修改场景

1.17:明确仅返回一条数据的语句可以使用limit 1
select * from users where user_name = "张三";
select * from users where user_name = "张三" limit 1;

加上limit 1关键字后,当程序匹配到一条数据时就会停止扫描,如果不加的情况下会将所有数据都扫描一次。

所以一般情况下,如果确定了只需要查询一条数据,就可以加上limit 1提升性能。

2:业内标准

2.1:3秒原则和5秒原则
  • 客户端访问时,能够在1s内得到响应,用户会觉得系统响应很快,体验非常好。
  • 客户端访问时,1~3秒内得到响应,处于可以接受的阶段,其体验感还算不错。
  • 客户端访问时,需要等待3~5秒时才可响应,这是用户就感觉比较慢了,体验有点糟糕。
  • 客户端访问时,一旦响应超过5秒,用户体验感特别糟糕,通常会选择离开或刷新重试。

上述这四条是用户体验感的四个等级,一般针对于C端业务而言,基本上都需要将接口响应速度控制到第二等级,即最差也要三秒内给用户返回响应

否则会导致体验感极差,从而让用户对产品留下不好的印象。

所谓的三秒原则通常是基于C端业务而言的,对于B端业务来说,通常用户的容忍度会高一些,也包括B端业务的业务逻辑会比C端更为复杂一些,所以可将响应速度控制到第三等级,也就是5s内能够得到响应。

针对于一些特殊类型的业务,如后台计算型的业务,好比跑批对账、定时调度…等,这类因为本身业务就特殊,因此可不关注其响应速度。

2.2:mysql的500ms原则

用户感受到的响应速度会由多方面的耗时组成,如下:

在这里插入图片描述

所谓给用户的响应时间其实会包含各方面的耗时,也就是这所有的过程加一块儿,必须要在1~3s内给出响应

而SQL耗时属于「系统耗时→数据操作耗时」这部分,因此留给SQL语句执行的时间最多只能有500ms

一般在用户量较大的门户网站中,甚至要求控制在10ms、30ms、50ms以内

二:MySQL索引优化

1:explain分析工具

在之前的’正确建立和使用索引‘简单的说了一下这个工具,是自带的一个执行分析工具,可使用于select、insert、update、delete、repleace等语句上,需要使用时只需在SQL语句前加上一个explain关键字即可,然后MySQL会对应语句的执行计划列出

在这里插入图片描述

1.1:id字段

这是执行计划的ID值,一条SQL语句可能会出现多步执行计划,所以会出现多个ID值,这个值越大,表示执行的优先级越高,同时还会出现四种情况:

  • ID相同:当出现多个ID相同的执行计划时,从上往下挨个执行。
  • ID不同时:按照ID值从大到小依次执行。
  • ID有相同又有不同:先从大到小依次执行,碰到相同ID时从上往下执行。
  • ID为空:ID=null时,会放在最后执行。
1.2:select_type字段

当前执行的select语句其具体的查询类型,有如下取值:

  • SIMPLE:简单的select查询语句,不包含union、子查询语句。
  • PRIMARY:union或子查询语句中,最外层的主select语句。
  • SUBQUEPY:包含在主select语句中的第一个子查询,如select … xx = (select …)。
  • DERIVED:派生表,指包含在from中的子查询语句,如select … from (select …)。
  • DEPENDENT SUBQUEPY:复杂SQL中的第一个select子查询(依赖于外部查询的结果集)。
  • UNCACHEABLE SUBQUERY:不缓存结果集的子查询语句。
  • UNION:多条语句通过union组成的查询中,第二个以及更后面的select语句。
  • UNION RESULT:union的结果集。
  • DEPENDENT UNION:含义同上,但是基于外部查询的结果集来查询的。
  • UNCACHEABLE UNION:含义同上,但查询出的结果集不会加入缓存。
  • MATERIALIZED:采用物化的方式执行的包含派生表的查询语句。

这个字段主要是说明当前查询语句所属的类型,以及在整条大的查询语句中,当前这个查询语句所属的位置。

1.3:table字段

表示当前这个执行计划是基于哪张表执行的,这里会写出表名,但有时候也不一定是物理磁盘中存在的表名,还有可能出现如下格式:

  • <derivenN>:基于id=N的查询结果集,进一步检索数据。
  • <unionM,N>:会出现在查询类型为UNION RESULT的计划中,表示结果由id=M,N…的查询组成。
  • <subqueryN>:基于id=N的子查询结果,进一步进行数据检索。
  • <tableName>:基于磁盘中已创建的某张表查询。

一句话总结就是:这个字段会写明,当前的这个执行计划会基于哪个数据集查询,有可能是物理表、有可能是子查询的结果、也有可能是其他查询生成的派生表。

1.4:partitions字段

这个字段在早版本的explain工具中不存在,这主要是用来显示分区的,因为后续版本的MySQL中支持表分区,该列的值表示检索数据的分区。

1.5:type字段

该字段表示当前语句执行的类型,可能出现的值如下:

  • all:全表扫描,基于表中所有的数据,逐行扫描并过滤符合条件的数据。
  • index:全索引扫描,和全表扫描类似,但这个是把索引树遍历一次,会比全表扫描要快。
  • range:基于索引字段进行范围查询,如between、<、>、in…等操作时出现的情况。
  • index_subquery:和上面含义相同,区别:这个是基于非主键、唯一索引字段进行in操作。
  • unique_subquery:执行基于主键索引字段,进行in操作的子查询语句会出现的情况。
  • index_merge:多条件查询时,组合使用多个索引来检索数据的情况。
  • ref_or_null:基于次级(非主键)索引做条件查询时,该索引字段允许为null出现的情况。
  • fulltext:基于全文索引字段,进行查询时出现的情况。
  • ref:基于非主键或唯一索引字段查找数据时,会出现的情况。
  • eq_ref:连表查询时,基于主键、唯一索引字段匹配数据的情况,会出现多次索引查找。
  • const:通过索引一趟查找后就能获取到数据,基于唯一、主键索引字段查询数据时的情况。
  • system:表中只有一行数据,这是const的一种特例。
  • null:表中没有数据,无需经过任何数据检索,直接返回结果。

这个字段的值很重要,它决定了MySQL在执行一条SQL时,访问数据的方式,性能从好到坏依次为:

  • 完整的性能排序:null → system → const → eq_ref → ref → fulltext → ref_or_null → index_merge → unique_subquery → index_subquery → range → index → all
  • 常见的性能排序:system → const → eq_ref → ref → fulltext → range → index → all

一般在做索引优化时,一般都会要求最好优化到ref级别,至少也要到range级别,也就是最少也要基于次级索引来检索数据,不允许出现index、all这类全扫描的形式。

1.6:possible_keys字段

这个字段会显示当前执行计划,在执行过程中可能会用到哪些索引来检索数据

⚠️ 可能会用到并不代表一定会用,在某些情况下,就算有索引可以使用,MySQL也有可能放弃走索引查询。

1.7:key字段

前面的possible_keys字段表示可能会用到的索引,而key这个字段则会显示具体使用的索引

一般情况下都会从possible_keys的值中,综合评判出一个性能最好的索引来进行查询,但也有两种情况会出现key=null的这个场景:

  • possible_keys有值,key为空:多半是由于表中数据不多,因此MySQL会放弃索引,选择走全表查询,也有可能是因为SQL导致索引失效。
  • possible_keys、key都为空:表示当前表中未建立索引、或查询语句中未使用索引字段检索数据。

默认情况下,possible_keys有值时都会从中选取一个索引,但这个选择的工作是由MySQL优化器自己决定的

如果你想让查询语句执行时走固定的索引,则可以通过force index、ignore index的方式强制指定。

1.8:key_len字段

这个表示对应的执行计划在执行时,使用到的索引字段长度,一般情况下都为索引字段的长度,但有三种情况例外:

  • 如果索引是前缀索引,这里则只会使用创建前缀索引时,声明的前N个字节来检索数据。
  • 如果是联合索引,这里只会显示当前SQL会用到的索引字段长度,可能不是全匹配的情况。
  • 如果一个索引字段的值允许为空,key_len的长度会为:索引字段长度+1。
1.9:ref字段

显示索引查找过程中,查询时会用到的常量或字段:

  • const:如果显示这个,则代表目前是在基于主键字段值或数据库已有的常量(如null)查询数据。
    • select … where 主键字段 = 主键值;
    • select … where 索引字段 is null;
  • 显示具体的字段名:表示目前会基于该字段查询数据。
  • func:如果显示这个,则代表当与索引字段匹配的值是一个函数,如:
    • select … where 索引字段 = 函数(值);
1.10:rows字段

这一列代表执行时,预计会扫描的行数

这个数字对于InnoDB表来说,其实有时并不够准确,但也具备很大的参考价值

如果这个值很大,在执行查询语句时,其效率必然很低,所以该值越小越好。

1.11:filtered字段

这个字段在早版本中也不存在,它是一个百分比值,意味着表中不会扫描的数据百分比

该值越小则表示执行时会扫描的数据量越大,取值范围是0.00~100.00。

1.12:extra字段

该字段会包含MySQL执行查询语句时的一些其他信息,这个信息对索引调优而言比较重要,可以带来不小的参考价值

这个字段会出现的值有很多种,如下:

  • Using index:表示目前的查询语句,使用了索引覆盖机制拿到了数据。
  • Using where:表示目前的查询语句无法从索引中获取数据,需要进一步做回表去拿表数据。
  • Using temporary:表示MySQL在执行查询时,会创建一张临时表来处理数据。
  • Using filesort:表示会以磁盘+内存完成排序工作,而完全加载数据到内存来完成排序。
  • Select tables optimized away:表示查询过程中,对于索引字段使用了聚合函数。
  • Using where;Using index:表示要返回的数据在索引中包含,但并不是索引的前导列,需要做回表获取数据。
  • NULL:表示查询的数据未被索引覆盖,但where条件中用到了主键,可以直接读取表数据。
  • Using index condition:和Using where类似,要返回的列未完全被索引覆盖,需要回表。
  • Using join buffer (Block Nested Loop):连接查询时驱动表不能有效的通过索引加快访问速度时,会使用join-buffer来加快访问速度,在内存中完成Loop匹配。
  • Impossible WHERE:where后的条件永远不可能成立时提示的信息,如where 1!=1。
  • Impossible WHERE noticed after reading const tables:基于唯一索引查询不存在的值时出现的提示。
  • const row not found:表中不存在数据时会返回的提示。
  • distinct:去重查询时,找到某个值的第一个值时,会将查找该值的工作从去重操作中移除。
  • Start temporary, End temporary:表示临时表用于DuplicateWeedout半连接策略,也就是用来进行semi-join去重。
  • Using MRR:表示执行查询时,使用了MRR机制读取数据。
  • Using index for skip scan:表示执行查询语句时,使用了索引跳跃扫描机制读取数据。
  • Using index for group-by:表示执行分组或去重工作时,可以基于某个索引处理。
  • FirstMatch:表示对子查询语句进行Semi-join优化策略。
  • No tables used:查询语句中不存在from子句时提示的信息,如desc table_name;。

🎉 基于Extra字段做个性能排序:Using index → NULL → Using index condition → Using where → Using where;Using index → Using join buffer → Using filesort → Using MRR → Using index for skip scan → Using temporary → Strart temporary,End temporary → FirstMatch

2:索引优化参考项

在做索引优化时,值得咱们参考的几个字段为:

  • key:如果该值为空,则表示未使用索引查询,此时需要调整SQL或建立索引。
  • type:这个字段决定了查询的类型,如果为indexall就需要进行优化。
  • rows:这个字段代表着查询时可能会扫描的数据行数,较大时也需要进行优化。
  • filtered:这个字段代表着查询时,表中不会扫描的数据行占比,较小时需要进行优化。
  • Extra:这个字段代表着查询时的具体情况,在某些情况下需要根据对应信息进行优化。

在explain语句后面紧跟着show warings语句,可以得到优化后的查询语句,从而看出优化器优化了什么。

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

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

相关文章

langchain教程-12.Agent/工具定义/Agent调用工具/Agentic RAG

前言 该系列教程的代码: https://github.com/shar-pen/Langchain-MiniTutorial 我主要参考 langchain 官方教程, 有选择性的记录了一下学习内容 这是教程清单 1.初试langchain2.prompt3.OutputParser/输出解析4.model/vllm模型部署和langchain调用5.DocumentLoader/多种文档…

大模型中提到的超参数是什么

在大模型中提到的超参数是指在模型训练之前需要手动设置的参数&#xff0c;这些参数决定了模型的训练过程和最终性能。超参数与模型内部通过训练获得的参数&#xff08;如权重和偏置&#xff09;不同&#xff0c;它们通常不会通过训练自动学习&#xff0c;而是需要开发者根据任…

位运算及常用技巧

涉及位运算的运算符如下表所示&#xff1a; 位运算的运算律&#xff1a; 负数的位运算 首先&#xff0c;我们要知道&#xff0c;在计算机中&#xff0c;运算是使用的二进制补码&#xff0c;而正数的补码是它本身&#xff0c;负数的补码则是符号位不变&#xff0c;其余按位取反…

hot100(8)

71.10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09; 动态规划 题解&#xff1a;10. 正则表达式匹配题解 - 力扣&#xff08;LeetCode&#xff09; 72.5. 最长回文子串 - 力扣&#xff08;LeetCode&#xff09; 动态规划 1.dp数组及下标含义 dp[i][j] : 下标i到…

二进制/源码编译安装httpd 2.4,提供系统服务管理脚本并测试

方法一&#xff1a;使用 systemd 服务文件 安装所需依赖 yum install gcc make apr-devel apr-util-devel pcre-devel 1.下载源码包 wget http://archive.apache.org/dist/httpd/httpd-2.4.62.tar.gz 2.解压源码 tar -xf httpd-2.4.62.tar.gz cd httpd-2.4.62 3.编译安装 指定…

Java 中 LinkedList 的底层源码

在 Java 的集合框架中&#xff0c;LinkedList是一个独特且常用的成员。它基于双向链表实现&#xff0c;与数组结构的集合类如ArrayList有着显著差异。深入探究LinkedList的底层源码&#xff0c;有助于我们更好地理解其工作原理和性能特点&#xff0c;以便在实际开发中做出更合适…

金蝶云星空k3cloud webapi报“java.lang.Class cannot be cast to java.lang.String”的错误

最近在对接金蝶云星空k3cloud webapi时&#xff0c;报一个莫名其妙的转换异常&#xff0c;具体如下&#xff1a; 同步部门异常! ERP接口登录异常&#xff1a;java.lang.Class cannot be cast to java.lang.String at com.jkwms.k3cloudSyn.service.basics.DeptK3CloudService.…

【Android】jni开发之导入opencv和libyuv来进行图像处理

做视频图像处理时需要对其进行水印的添加&#xff0c;放在应用层调用工具性能方面不太满意&#xff0c;于是当下采用opencvlibyuv方法进行处理。 对于Android的jni开发不是很懂&#xff0c;我的需求是导入opencv方便在cpp中调用&#xff0c;但目前找到的教程都是把opencv作为模…

【MySQL】centos 7 忘记数据库密码

vim /etc/my.cnf文件&#xff1b; 在[mysqld]后添加skip-grant-tables&#xff08;登录时跳过权限检查&#xff09; 重启MySQL服务&#xff1a;sudo systemctl restart mysqld 登录mysql&#xff0c;输入mysql –uroot –p&#xff1b;直接回车&#xff08;Enter&#xff09; 输…

国产编辑器EverEdit - 自定义标记使用详解

1 自定义标记使用详解 1.1 应用场景 当阅读日志等文件&#xff0c;用于调试或者检查问题时&#xff0c;往往日志中会有很多关键性的单词&#xff0c;比如&#xff1a;ERROR, FATAL等&#xff0c;但由于文本模式对这些关键词并没有突出显示&#xff0c;造成检查问题时&#xff…

Golang 并发机制-6:掌握优雅的错误处理艺术

并发编程可能是提高软件系统效率和响应能力的一种强有力的技术。它允许多个工作负载同时运行&#xff0c;充分利用现代多核cpu。然而&#xff0c;巨大的能力带来巨大的责任&#xff0c;良好的错误管理是并发编程的主要任务之一。 并发代码的复杂性 并发编程增加了顺序程序所不…

JVM 四虚拟机栈

虚拟机栈出现的背景 由于跨平台性的设计&#xff0c;Java的指令都是根据栈来设计的。不同平台CPU架构不同&#xff0c;所以不能设计为基于寄存器的。优点是跨平台&#xff0c;指令集小&#xff0c;编译器容易实现&#xff0c;缺点是性能下降&#xff0c;实现同样的功能需要更多…

鼠标拖尾特效

文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果&#xff0c;能够为网页增添独特的视觉体验。它通常通过JavaScript和C…

6-图像金字塔与轮廓检测

文章目录 6.图像金字塔与轮廓检测(1)图像金字塔定义(2)金字塔制作方法(3)轮廓检测方法(4)轮廓特征与近似(5)模板匹配方法6.图像金字塔与轮廓检测 (1)图像金字塔定义 高斯金字塔拉普拉斯金字塔 高斯金字塔:向下采样方法(缩小) 高斯金字塔:向上采样方法(放大)…

RNN/LSTM/GRU 学习笔记

文章目录 RNN/LSTM/GRU一、RNN1、为何引入RNN&#xff1f;2、RNN的基本结构3、各种形式的RNN及其应用4、RNN的缺陷5、如何应对RNN的缺陷&#xff1f;6、BPTT和BP的区别 二、LSTM1、LSTM 简介2、LSTM如何缓解梯度消失与梯度爆炸&#xff1f; 三、GRU四、参考文献 RNN/LSTM/GRU …

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记 文章目录 qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记1.例程运行效果2.例程缩略图3.项目文件列表4.main.qml5.main.cpp6.CMakeLists.txt 1.例程运行效果 运行该项目需要自己准备一个模型文件 2.例程缩略图…

以太坊入门【详解】

以太坊的组成部分 P2P网络&#xff1a;以太坊在以太坊网络上运行&#xff0c;该网络可在TCP端口30303上寻址&#xff0c;并运行一个协议。交易&#xff1a;以太坊交易时网络消息&#xff0c;其中包括发送者&#xff0c;接受者&#xff0c;值和数据的有效载荷以太坊虚拟机&…

实验十四 EL和JSTL

实验十四 EL和JSTL 一、实验目的 1、掌握EL表达式的使用 2、掌握JSTL的使用 二、实验过程 1、在数据库Book中建立表Tbook&#xff0c;包含图书ID&#xff0c;图书名称&#xff0c;图书价格。实现在bookQuery.jsp页面中模糊查询图书&#xff0c;如果图书的价格在50元以上&#…

安装和卸载RabbitMQ

我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/SUWXdDb0UoCV86xP6b3c7qtMn6b 使用Ubuntu环境进行安装 一、安装Erlang 在安装RabbitMQ之前,我们需要先安装Erlang,RabbitMQ需要Erlang的语言支持 #安装Erlang sudo apt-get install erlang 在安装的过程中,会弹出一段信息,此…

音视频多媒体编解码器基础-codec

如果要从事编解码多媒体的工作&#xff0c;需要准备哪些更为基础的内容&#xff0c;这里帮你总结完。 因为数据类型不同所以编解码算法不同&#xff0c;分为图像、视频和音频三大类&#xff1b;因为流程不同&#xff0c;可以分为编码和解码两部分&#xff1b;因为编码器实现不…