高性能MySQL-查询性能优化
查询性能优化
- 1、为什么查询这么慢
- 2、慢查询基础:优化数据访问
- 2.1 是否向数据库请求了不需要的数据
- 2.2 MySQL是否存在扫描额外的记录
- 3、重构查询方式
- 3.1 一个复杂查询还是多个简单查询
- 3.2 切分查询
- 3.3 分解联接查询
- 4、查询执行的基础
- 4.1 MySQL的客户端/服务器通信协议
- 4.2 查询状态
- 4.3 查询优化处理
- 5、MySQL查询优化器的局限性
- 5.1 UNION的限制
- 5.2 并行执行
- 5.3 同一个表中查询和更新
- 6、优化特定类型的查询
- 6.1 优化count()查询
- 6.2 使用WITH ROLLUP优化GROUP BY
- 6.3 优化limit和offset子句
- 6.4 优化SQL CALC FOUND ROWS
- 6.5 优化UNION查询
如有侵权,请联系~
如有错误,也欢迎批评指正~
本篇文章大部分是来自学习《高性能MySQL》的笔记
1、为什么查询这么慢
查询优化、索引优化、库表结构优化需要齐头并进,一个不落
快速查询真正重要的是响应时间。如果把查询当做一个任务,那么这个任务会由一系列的子任务组成,每个子任务都需要消耗一定的时间。优化查询其实就是优化子任务,要么消除一些子任务,要么减少某些子任务的执行次数,要么让子任务执行的更快。
在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络、CPU计算、生成统 计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用 操作,这些调用需要在内存操作、CPU操作和内存不足时导致的I/O操作上消耗时间。
在每一个消耗大量时间的查询案例中,我们都能看到一些不必要的操作、某些操作被额外地重复了很多次、某些操作执行得太慢等。优化查询的目的就是减少和消除这些操作所花费的时间。
2、慢查询基础:优化数据访问
查询性能很差的最常见原因:访问的数据太多。大部分性能低下的查询都可以通过减少访问的数据量的
方式进行优化。对于低效的查询,我们发现通过下面两个步骤来分析总是很有效:
- 确认应用程序是否在检索大量且不必要的数据。访问了太多的行或者列
- 确认MySQL服务器层是否在分析大量不需要的数据行
2.1 是否向数据库请求了不需要的数据
有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃。这会给 MySQL服务器带来额外的负担,并增加网络开销,另外,这也会消耗应用服务器的CPU和内存资源。
- 查询了不需要的数据
- 多表联查的时候返回了所有的列
- 总是取所有的列:select *
- 重复相同的查询
2.2 MySQL是否存在扫描额外的记录
在确定查询只返回需要的数据以后,接下来应该看看查询为了返回结果是否扫描了过多的数据。对于MySQL,最简单的衡量查询开销的三个指标如下:响应时间、扫描的行数、返回的行数。
3、重构查询方式
优化查询的目标:找到获得实际需要的结果的替代方法。不一定和优化前的数据完全一致,可以是相同结果的等价形式。
3.1 一个复杂查询还是多个简单查询
设计查询的时候,一个需要考虑的重要问题:是否需要将一个复杂的查询转换为多个简单的查询。传统的实现认为:网络通信、查询解析和优化都是代价比较高的操作,所以让数据库做尽可能多的工作。
但是这对MySQL不适用,原因:
- MySQL从设计上就将连接和断开连接都变的很轻量,在返回一个小的查询结果方面很高效。
- 并且现代网络也快很多。
- 在某些版本的MySQL中,即使在一台通用服务器上,也能够运行每秒超 过10万次的简单查询。
- 在MySQL内部,每秒能够扫描内存中上百万行的数据,相比之下,MySQL响应数据给客户端就慢得多了。
所以将一个大查询分解为多个小查询是很有必要的。但也不是一个查询就能完成的非要转换为多个查询。
3.2 切分查询
对于一个大查询,分而治之,将一个大查询转换为多个小查询,每个小查询的功能完全一样,每次只返回一小部分结果。例如删除旧数据,不要一次删除所有数据,这样可能需要一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。需要注意:如果每次删除数据后, 都暂停一会儿再做下一次删除,也可以将服务器上原本一次性的压力分散到一个很长的时 间段中,可以大大降低对服务器的影响,还可以大大减少删除时锁的持有时间。
3.3 分解联接查询
很多高性能的应用都会对联接查询进行分解。即,对每个表进行单次查询,然后在应用程序中进行联接。这样做的好处:
- 让缓存的效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。
- 减少锁竞争
- 在应用层做联接,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
- 可以减少对冗余记录的访问。在应用层做联接查询,意味着对于某条记录应用只需要查询一次,而在数据库中做联接查询,则可能需要重复地访问一部分数据。从这 点看,这样的重构还可能会减少网络和内存的消耗。
4、查询执行的基础
4.1 MySQL的客户端/服务器通信协议
MySQL的客户端和服务器之间的通信协议是“半双工”的,这意味着,在任何时刻,要么是由服务器向客户端发送数据,要么是由客户端向服务器发送数据,这两个动作不能同时发生。
这种协议让MySQL通信变得简单快速,但是也从很多地方限制了MySQL。一个明显的限制是,这意味着没法进行流量控制。一旦一端开始发送消息,另一端要接收完整个消息才能响应它。
客户端用一个单独的数据包将查询传给服务器。这也是为什么当查询的语句很长的时候,参数max_allowed_packet就特别重要了。一旦客户端发送了请求,它能做的事情就只是等待结果了。
一般的服务器响应给用户的数据通常很多,由多个数据包组成。当服务器开始响应客户端请求时,客户端必须完整地接收整个返回结果,而不能简单地只取前面几条结果, 然后让服务器停止发送数据。
4.2 查询状态
对于一个MySQL连接,或者一个线程,任何时刻都有一个状态,该状态表示了MySQL当 前正在做什么。有很多种方式能查看当前的状态,最简单的是使用SHOW FULL PROCESSLIST命令(该命令返回结果中的Command列,其就表示当前的状态)

| Command | 描述 |
|---|---|
| Sleep | 线程正在等待客户端发送新的请求 |
| Query | 线程正在执行查询或者正在将结果发送给客户端 |
| Locked | 在MySQL服务器层,该线程正在等待表锁。在存储引擎级别实现的锁,例如InnoDB 的行锁,并不会体现在线程状态中。 |
| Analyzing and statistics | 线程正在检查存储引擎的统计信息,并优化查询。 |
| Sorting result | 线程正在对结果集进行排序 |
| Copying to tmp table [on disk] | 线程正在执行查询,并且将其结果集复制到一个临时表中,这种状态一般要么是在做 GROUP BY操作,要么是在进行文件排序操作,或者是在进行UNION操作。如果这 个状态后面还有“on disk”标记,那表示MySQL正在将一个内存临时表放到磁盘上。 |
在一个繁忙的服务器上,通过查看线程状态可能会看到大量的不正常的状态,例如,statistics正占用大量的时间。这 通常表示,某个地方有异常了。
4.3 查询优化处理
语法解析器和预处理:
MySQL通过关键字将SQL语句进行解析,并生成一棵对应的“解析树”。MySQL解 析器将使用MySQL语法规则验证和解析查询。例如,它将验证是否使用了错误的关键字,使用关键字的顺序是否正确,或者它还会验证引号是否能前后正确匹配。
预处理器检查生成的解析树,以查找解析器无法解析的其他语义,例如,这里将检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义。下一步预处理器会验证权限。这通常很快,除非服务器上有非常多的权限配置。
查询优化器:
由优化器将其转化成查询执行计划。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。
MySQL使用基于成本的优化器,它将尝试预测一个查询使用某种执行计划时的成本,并 选择其中成本最小的一个。最初,成本的最小单位是随机读取一个4KB数据页的成本,后来成本计算公式变得更加复杂,并且引入了一些“因子”来估算某些操作的代价,如执行一次WHERE条件比较的成本。优化器在评估成本的时候并不考虑任何层面的缓存带来的影响,它假设读取任何数据都需要一次磁盘I/O。
MySQL的查询优化器是一个非常复杂的软件,它使用了很多优化策略来生成一个最优的 执行计划。优化策略可以简单地分为两种,一种是静态优化,一种是动态优化。
静态优化可以直接对解析树进行分析,并完成优化。例如,优化器可以通过一些简单的代数变换将 WHERE条件转换成另一种等价形式。静态优化不依赖于特别的数值,如WHERE条件中带入的一些常数等。静态优化在第一次完成后就一直有效,即使使用不同的参数重复执行 查询也不会发生变化,可以认为这是一种“编译时优化”。
动态优化则和查询的上下文有关,也可能和很多其他因素有关,例如WHERE条件 中的取值、索引中条目对应的数据行数等。这需要在每次查询的时候都重新评估,可以认 为这是“运行时优化”。
MySQL可以优化的类型,但不限于:
| 优化类型 | 描述 |
|---|---|
| 重新定义联接表的顺序 | 数据表的联接并不总是按照在查询中指定的顺序进行。决定联接的顺序是优化器很重要的一个功能 |
| 将外联接转化成内联接 | 并不是所有的OUTER JOIN语句都必须以外联接的方式执行。诸多因素,例如 WHERE条件、库表结构都可能会让外联接等价于一个内联接。MySQL能够识别这一 点并重写查询,让其可以调整联接顺序。 |
| 使用代数等价变换规则 | MySQL可以使用一些代数等价变换规则来简化并规范表达式。它可以合并和减少一些比较,还可以移除一些恒成立和一些恒不成立的判断。 |
| 优化COUNT()、MIN()和MAX() | 索引和列是否可为空通常可以帮助MySQL优化这类表达式。例如,要找到某一列的 最小值,只需要查询对应B-tree索引最左端的记录,MySQL可以直接获取索引的第一 行记录。在优化器生成执行计划的时候就可以利用这一点,在B-tree索引中,优化器 会将这个表达式作为一个常数对待。 |
| 预估并转化为常数表达式 | 当MySQL检测到一个表达式可以转化为常数的时候,就会一直把该表达式作为常数 进行优化处理。在优化阶段,有时候一个查询也能够转化为一个常数。select film.film.film_id,film_actor.actor_id from film join film_actor using film_id where film.film_id=1 第一步先从film表找到 需要的行。因为在film_id列上有主键索引,所以MySQL优化器知道这只会返回一行数 据,优化器在生成执行计划的时候,就已经通过索引信息知道将返回多少行数据了。因为 查询优化器已经明确知道有多少个值(WHERE条件中的值)需要做索引查询,所以这里 的表访问类型是const。在执行计划的第二步时,MySQL将第一步中返回的film_id列当作一个已知取值的列来处理。因为优化器清楚在第一步执行完成后,该值就会是明确的了。注意,正如在第一步中一样,使用film_actor字段对表的访问类型也是const。 |
| 索引覆盖 | 当索引中的列包含所有查询中需要使用的列的时候,MySQL就可以使用索引返回需 要的数据,而无须查询对应的数据行 |
| 子查询优化 | MySQL在某些情况下可以将子查询转换为一种效率更高的形式,从而减少多个查询 多次对数据进行访问。 |
| 提前终止查询 | 在发现已经满足查询需求的时候,MySQL总是能够立刻终止查询。一个典型的例子 就是当使用了LIMIT子句的时候。除此之外,MySQL在其他几类情况下也会提前终 止查询,例如发现了一个不成立的条件,这时MySQL可以立刻返回一个空结果。 |
| 等值传播 | 如果两列的值可通过等式联接,那么MySQL能够把其中一列的WHERE条件传递到另一列上.select film.film.film_id,film_actor.actor_id from film join film_actor using film_id where film.film_id=1 |
| 列表IN()的比较 | 在很多数据库服务器中,IN()完全等同于多个OR条件的子句,因为这两者是完全等 价的。在MySQL中这点是不成立的,MySQL将IN()列表中的数据先进行排序,然后 通过二分查找的方式来确定列表中的值是否满足条件,这是一个O(logn)复杂度的 操作 |
MySQL如何执行联接查询
MySQL中使用的术语“联接”(对应英文为Join)的范围可能比你熟悉的更广泛。总的来 说,MySQL认为每一个查询都是联接——不仅是匹配两张表中对应行的查询,而是每一 个查询、每一个片段(包括子查询,甚至基于单表的SELECT)都是联接。
UNION查询:MySQL将一系列的单个查询结果放在一个临时表中,然后重新从临时表中读取数据完成UNION。
MySQL的联接执行策略很简单:MySQL对任何联接都执行嵌套循环联接操作,即 MySQL先在一个表中循环取出单条数据,然后再嵌套循环到下一个表中寻找匹配的行, 依次下去,直到找到所有表中匹配的行为止。最后根据各个表匹配的行,返回查询中需要 的各列。MySQL会尝试在最后一个联接表中找到所有匹配的行,如果最后一个联接表无 法找到更多的行,MySQL返回到上一层次的联接表,看是否能够找到更多的匹配记录, 依此类推,迭代执行.
执行计划
MySQL不像其他其他关系型数据库生成字节码来执行查询,而是通过生成一个查询指令树,然后通过查询执行引擎执行完成这棵指令树并返回结果。

联接查询优化器
MySQL查询优化器最重要的一部分就是联接查询优化器,它决定了多个表联接时的顺 序。通常多表联接的时候,可以有多种不同的联接顺序来获得相同的执行结果。联接查询 优化器通过评估不同顺序时的成本来选择一个成本最低的联接顺序。
排序优化
无论如何排序都是一个成本很高的操作,所以从性能角度考虑,应尽可能避免排序或者尽可能避免对大量数据进行排序。
当不能使用索引生成排序结果的时候,MySQL需要自己进行排序,如果数据量小则在内存中进行,如果数据量大则需要使用磁盘,不过MySQL将这个过程统一称为文件排序 (filesort)。
如果需要排序的数据量小于“排序缓冲区”,MySQL使用内存进行快速排序操作。如果内存不够排序,那么MySQL会先将数据分块,对每个独立的块使用“快速排序”进行排序, 并将各个块的排序结果存放在磁盘上,然后将各个排好序的块进行合并(merge),最后 返回排序结果。
排序类型分两种:单次传输排序【一次全量数句读取,包含了所有的列,占用空间】和两次传输排序【第一次只读取主见和排序字段,第二次对排序的记录进行随机IO,性能差】。
在联接查询的时候如果需要排序,MySQL会分两种情况来处理这样的文件排序。如果 ORDER BY子句中的所有列都来自联接的第一个表,那么MySQL在联接处理第一个表的 时候就进行文件排序。如果是这样,那么在MySQL的EXPLAIN结果中可以看到Extra字段 会有“Using filesort”字样。除此之外的所有情况,MySQL都会先将联接的结果存放到一个 临时表中,然后在所有的联接都结束后,再进行文件排序。在这种情况下,在MySQL的 EXPLAIN结果的Extra字段可以看到“Using temporary;Using filesort”字样。如果查询中有 LIMIT的话,LIMIT也会在文件排序之后应用,所以即使需要返回较少的数据,临时表和 需要排序的数据量仍然会非常大。
查询执行引擎
MySQL只是简单地根据执行计划给 出的指令逐步执行。在根据执行计划逐步执行的过程中,有大量的操作需要通过调用存储 引擎实现的接口来完成,这些接口也就是我们称为“handler API”的接口。查询中的每一个表都由一个handler的实例表示。如果一个表在查询中出现了三次,服务器会创建三个 handler对象。前面我们有意忽略了这一点,实际上,MySQL在优化阶段就为每个表创建 了一个handler实例,优化器根据这些实例的接口可以获取表的相关信息,包括表的所有列名、索引统计信息等等。
将结果返回给客户端
MySQL将结果集返回客户端是一个增量且逐步返回的过程。例如,我们回头看看前面的联接操作,一旦服务器处理完最后一个联接表,开始生成第一条结果时,MySQL就可以 开始向客户端逐步返回结果集了。这样处理有两个好处:服务器端无须存储太多的结果, 也就不会因为要返回太多结果而消耗太多内存。另外,这样的处理也可让MySQL客户端第一时间获得返回的结果。结果集中的每一行都会以一个满足MySQL客户端/服务器通信协议的封包发送,再通过TCP协议进行传输,在TCP传输的过程中,可能对MySQL的封 包进行缓存,然后批量传输。
5、MySQL查询优化器的局限性
5.1 UNION的限制
有时,MySQL无法将限制条件从UNION的外层“下推”到内层,这使得原本能够限制部分返回结果的条件无法应用到内层查询的优化上。
如果希望UNION的各个子句能够根据LIMIT只取部分结果集,或者希望能够先排好序再合并结果集的话,就需要在UNION的各个子句中分别使用这些子句。例如,想将两个子查询结果联合起来,然后再取前20条记录,那么MySQL会将两个表存放到同一个临时表 中,然后再取出前20行记录:
(select actor_name from film_actor)
UNION ALL
(select user_name from user)
limit 20
(select actor_name from film_actor limit 20)
UNION ALL
(select user_name from user limit 20)
limit 20
5.2 并行执行
MySQL无法利用多核特性来并行执行查询。很多其他的关系数据库能够提供这个特性, 但是MySQL做不到。这里特别指出是想告诉读者不要花时间去尝试寻找并行执行查询的方法。
5.3 同一个表中查询和更新
MySQL不允许对一张表同时进行查询和更新。这其实并不是优化器的限制。
update film as out_film
set actor_count = (select count(*) from film as inner_filmwhere out_film.film_name = inner_film.film_name
);
6、优化特定类型的查询
6.1 优化count()查询
COUNT()是一个特殊的函数,有两种非常不同的作用:它可以统计某列的值的数量,也可以统计行数。在统计列值时要求列值是非空的(不统计NULL)。如果在COUNT()的括 号中指定了列或者列的表达式,则统计的就是这个表达式有值的结果数。COUNT()的另一个作用是统计结果集的行数。当MySQL确认括号内的表达式值不可能为 空时,实际上就是在统计行数COUNT(*)。
使用近似值
某些业务场景并不要求完全精确的统计值,此时可以用近似值来代替。 EXPLAIN出来的优化器估算的行数就是一个不错的近似值,执行EXPLAIN并不需要真正 地去执行查询,所以成本很低。
优化联接查询
- 确保ON或者USING子句中的列上有索引。在创建索引的时候就要考虑到联接的顺序。当表A和表B用列c联接的时候,如果优化器的联接顺序是B、A,那么就不需 要在B表的对应列上建索引。没有用到的索引只会带来额外的负担
- 确保任何GROUP BY和ORDER BY中的表达式只涉及一个表中的列,这样MySQL 才有可能使用索引来优化这个过程。
- 当升级MySQL的时候需要注意:联接语法、运算符优先级等其他可能会发生变化的地方。因为以前是普通联接的地方可能会变成笛卡儿积,不同类型的联接可能会 生成不同的结果,甚至会产生语法错误。
6.2 使用WITH ROLLUP优化GROUP BY
with rollup是MySQL对返回的分组结果再做一次超级聚合,使用group by进行分组之后,with rollup会新增加一行对所有的分组数据再进行一次聚合。
6.3 优化limit和offset子句
在系统中需要进行分页操作的时候,我们通常会使用LIMIT加上偏移量的办法实现,同时 加上合适的ORDER BY子句。如果有对应的索引,通常效率会不错,否则,MySQL需要 做大量的文件排序操作。
一个非常常见又令人头疼的问题是,在偏移量非常大的时候,例如,可能是LIMIT 1000,20这样的查询,这时MySQL需要查询10020条记录然后只返回最后20条,前面10 000条记录都将被抛弃,这样的代价非常高。如果所有的页面被访问的频率都相同,那么 这样的查询平均需要访问半个表的数据。要优化这种查询,要么是在页面中限制分页的数量,要么是优化大偏移量的性能。
优化此类分页查询的一个最简单的办法就是尽可能地使用索引覆盖扫描,而不是查询所有的行。然后根据需要做一次联接操作再返回所需的列【延迟联接】。在偏移量很大的时候,这样做的效率会有非常大的提升。
select film_id,film_name from film order by title limit 50,5;
修改为:
select film_id,film_name from film
join(select film_id from film order by title limit 50,5
) as temp
on film.film_id = temp.film_id;
它允许服务器在不访问行的情况下检查索引中尽可能少的数据,然后,一旦找到所需的行,就将它们与整个表联接,以从该行中检索其他列。
有时候也可以将LIMIT查询转换为已知位置的查询,让MySQL通过范围扫描获得对应的结果。LIMIT和OFFSET的问题,其实是OFFSET的问题,它会导致MySQL扫描大量不需要的行然后再抛弃掉。如果可以使用书签记录上次取数据的位置,那么下次就可以直接从该书签 记录的位置开始扫描,这样就可以避免使用OFFSET。
6.4 优化SQL CALC FOUND ROWS
分页的时候,另一个常用的技巧是在LIMIT语句中加上SQL_CALC_FOUND_ROWS提示 (hint),这样就可以获得去掉LIMIT以后满足条件的行数,因此可以作为分页的总数。 看起来,MySQL做了一些非常“高深”的优化,像是通过某种方法预测了总行数。但实际 上,MySQL只有在扫描了所有满足条件的行以后,才会知道行数,所以加上这个提示以 后,不管是否需要,MySQL都会扫描所有满足条件的行,然后再抛弃掉不需要的行,而 不是在满足LIMIT的行数后就终止扫描。所以该提示的代价可能非常高。
// 获取数据记录
mysql> select sql_calc_found_rows * from user limit 2;
// 获取总数,即select count(*) from user
mysql> select found_rows();
一个更好的设计是将具体的页数换成“下一页”按钮,假设每页显示20条记录,那么我们每 次查询时都是用LIMIT返回21条记录并只显示20条,如果第21条存在,那么就显示“下一 页”按钮,否则就说明没有更多的数据,也就无须显示“下一页”按钮了。
6.5 优化UNION查询
MySQL总是通过创建并填充临时表的方式来执行UNION查询,因此很多优化策略在UNION查询中都没法很好地被使用。经常需要手工地将WHERE、LIMIT、ORDER BY等 子句“下推”到UNION的各个子查询中,以便优化器可以充分利用这些条件进行优化(例 如,直接将这些子句冗余地写一份到各个子查询)。
除非你确实需要服务器消除重复的行,否则一定要使用UNION ALL,这一点很重要。如 果没有ALL关键字,MySQL会给临时表加上DISTINCT选项,这会导致对整个临时表的数据做唯一性检查。这样做的代价非常高。即使有ALL关键字,MySQL仍然会使用临时表 存储结果。事实上,MySQL总是将结果放入临时表,然后再读出,再返回给客户端,虽 然很多时候这样做是没有必要的(例如,MySQL可以直接把这些结果返回给客户端)。
相关文章:
高性能MySQL-查询性能优化
查询性能优化 1、为什么查询这么慢2、慢查询基础:优化数据访问2.1 是否向数据库请求了不需要的数据2.2 MySQL是否存在扫描额外的记录 3、重构查询方式3.1 一个复杂查询还是多个简单查询3.2 切分查询3.3 分解联接查询 4、查询执行的基础4.1 MySQL的客户端/服务器通信…...
如何有效修复ffmpeg.dll错误:一站式解决方案指南
当您遇到提示“ffmpeg.dll文件丢失”的错误时,这可能导致相关的应用程序无法启动或运行异常。本文将详细介绍如何有效地解决ffmpeg.dll文件丢失的问题,确保您的应用程序能够恢复正常运行。 ffmpeg.dll是什么?有哪些功能? ffmpeg.…...
8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全
8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net[md]启动 Debug,它是可用于测试和调试 MS-DOS 可执行文件的程序。 Debug [[drive:][path] filename [parameters]] 参数 [drive:…...
查看mysql的冷数据配置比例
查看mysql的冷数据配置比例 -- 真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷热数据的比例是由innodb_old_blocks_pct参数控制的,它默认是37,也就是说冷数据占比37%。 show GLO…...
【Java基础面试题028】Java中的hashCode和equals方法,与==操作符有什么区别?
回答重点 hashcode、equals 和 都是Java中用于比较对象的三种方式,但是它们的用途和实现还是有挺大区别的。 hashcode用于散列存储结构中确定对象的存储位置。可用于快速比较两个对象是否不同,因为如果它们的哈希码不同,那么它们肯定不相等…...
在C#中测试比较目录的不同方法以查看它们有哪些共同的文件
C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序,并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息,请参阅该示例。 Kur…...
harbor离线安装 配置https 全程记录
1. 下载harbor最新版本 下载网址: 找最新的版本: https://github.com/goharbor/harbor/releases/download/v2.11.2/harbor-offline-installer-v2.11.2.tgz 这里我直接使用迅雷下载, 然后上传 1.1解压 sudo tar -xf harbor-offline-installer-v2.11.2.tgz -C /opt/ 2. 配置Harb…...
C++简明教程(文章要求学过一点C语言)(5)
在开始之前必须阅读这个文章 https://blog.csdn.net/weixin_45100742/article/details/135152562 这篇文章完全是对C语言的补课,如果C语言学的好,可跳过。 变量、数据类型与运算符 在 C 编程中,理解变量、数据类型和运算符是构建程序的基石…...
Halcon单相机+机器人=眼在手上#标定心得
首先,这个标定板肯定是放在我们要作业的工作台上的 目的 **1,得到标定物(工作台)与机器人底座之间的pose转换关系。2,得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1,标定板与机器人底座b…...
【hackmyvm】Diophante 靶场
1. 基本信息^toc 这里写目录标题 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. knock 3. WordPress利用3.1. wpscan扫描3.2. smtp上传后门 4. 提权4.1. 提权leonard用户4.2. LD劫持提权root 靶机链接 https://hackmyvm.eu/machines/machine.php?vmDiophante 作者…...
C++类的继承关系中什么时候要用到上行转换和下行转换
一、C类继承关系中的上行转换 1. 多态性实现 在C中,上行转换(将派生类转换为基类)是实现多态性的关键。例如,当有一个基类Animal,以及派生类Dog和Cat。如果有一个函数接受Animal类型的参数,我们可以将Dog或…...
Ubuntu 22.04永久保存路由
在 Ubuntu 22.04 上,可以按照以下方式配置让流量访问 172.19.201.207 走指定的路由。 1. 临时添加路由 临时路由规则只在当前系统会话中有效,重启后会丢失。 添加路由规则 运行以下命令: sudo ip route add 172.19.201.207 via 192.168.2…...
数据结构十大排序之(冒泡,快排,并归)
接上期: 数据结十大排序之(选排,希尔,插排,堆排)-CSDN博客 前言: 在计算机科学中,排序算法是最基础且最重要的算法之一。无论是大规模数据处理还是日常的小型程序开发,…...
OpenFeign源码
openfeign是通过FeignClientFactoryBean生成动态代理对象的方式实现http客户端无感调用,可以做到像定义接口一样写http客户端调用代码。 配置Feign接口后,我们通常会在SpringBoot项目启动类上标记EnableFeignClients,这个是生成动态代理对象的…...
sql server索引优化语句
第一步 建一个测试表 --create table TestUsers --( -- Id int primary key identity(1,1), -- Username varchar(30) not null, -- Password varchar(10) not null, -- CreateDateTime datetime not null --)第二步 插入100w数据 大概1分钟执行时间 ----插入数据…...
深度学习之超分辨率算法——SRGAN
更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…...
16.2、网络安全风险评估技术与攻击
目录 网络安全风险评估技术方法与工具 网络安全风险评估技术方法与工具 资产信息收集,可以通过调查表的形式把我们各类的资产信息进行一个统计和收集,掌握被评估对象的重要资产分布,进而分析这些资产关联的业务面临的安全威胁以及存在的安全…...
【项目管理】GDB调试
gdb(GNU Debugger) 是 Linux 和嵌入式开发中最常用的调试工具之一,可以用来调试 C/C 程序、排查崩溃、分析程序流程等。在嵌入式开发中,gdb 还可以通过远程调试(gdbserver)调试目标设备上的程序。 这篇文章…...
ChatGPT生成接口测试用例(一)
用ChatGPT做软件测试 接口测试在软件开发生命周期中扮演着至关重要的角色,有助于验证不同模块之间的交互是否正确。若协议消息被恶意修改,系统是否能够恰当处理,以确保系统的功能正常运行,不会出现宕机或者安全问题。 5.1 ChatGP…...
2024 年 IA 技术大爆发深度解析
摘要: 本文旨在深入剖析 2024 年 IA 技术大爆发所引发的多方面反响。通过对产业变革、经济影响、就业市场、社会影响、政策与监管以及未来展望等维度的探讨,揭示 IA 技术在这一关键时期对全球各个层面带来的深刻变革与挑战,并提出相应的思考与…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
