MySQL 索引优化:提升查询效率的关键

news2024/12/19 3:05:48

一、引言

MySQL 索引在数据库性能优化中起着至关重要的作用。本文将深入探讨 MySQL 索引优化的各种技巧,帮助读者提升查询效率。

在当今数据驱动的时代,数据库的性能对于各种应用程序至关重要。MySQL 作为广泛使用的关系型数据库管理系统,其索引功能是提升查询效率的关键。索引就如同书籍的目录,能够快速定位到所需的数据,避免全表扫描,从而大大减少查询时间。

MySQL 索引是一种数据结构,旨在提高数据库中数据的检索速度。它允许数据库系统快速定位数据,避免全表扫描,从而提高查询效率。索引通过在表中的列上创建一种特殊的结构来实现其功能。这种结构通常以树形数据结构(如 B-Tree)或哈希表的形式存在。当数据库执行查询时,索引可以显著减少查询所需的时间,特别是当表的数据量很大时。

索引的作用与好处众多。首先,它能够提高查询速度,允许数据库系统快速定位到数据所在的行,这对于大型表尤其重要。其次,索引可以减少 I/O 操作,通过使用索引,数据库系统可以减少磁盘上的数据扫描次数,从而减少 I/O 操作。此外,索引还能加速排序和分组操作,以及简化 JOIN 操作。在 JOIN 操作中,合理的索引可以显著提高查询速度。同时,索引还可以提供数据的唯一性约束,确保某些列的数据唯一性。然而,需要注意的是,索引也会增加写操作(如 INSERT 和 UPDATE)的成本,因为每次插入新数据或更新现有数据时,都需要更新索引结构。因此,在创建索引时需要权衡查询效率和写操作性能。

二、索引基础

(一)什么是索引

索引是一种数据结构,用于提高数据检索效率,类似书籍目录,加速数据查询过程。

索引在 MySQL 数据库中扮演着重要的角色,它就像书籍的目录一样,能够快速定位到所需的数据,避免全表扫描,从而大大减少查询时间。MySQL 中的索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

(二)索引的种类

  1. B-Tree 索引:适用于大多数场景,尤其是范围查询和排序操作。

B-Tree 索引不再是二叉搜索,而是 N 叉搜索,树的高度会降低,查询快。叶子节点,非叶子节点,都可以存储数据,且可以存储多个数据。通过中序遍历,可以访问树上所有节点。B-Tree 被作为实现索引的数据结构被创造出来,是因为它能够完美的利用 “局部性原理”。内存读写快,磁盘读写慢,而且慢很多。磁盘预读:磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载一些看起来是冗余的数据,如果未来要读取的数据就在这一页中,可以避免未来的磁盘读写,提高效率(通常,一页数据是 4K)。局部性原理:软件设计要尽量遵循 “数据读取集中” 与 “使用到一个数据,大概率会使用其附近的数据”,这样磁盘预读能充分提高磁盘 IO 效能。

B+TREE 改进点及优势所在:仍然是 N 叉树,层级小,非叶子节点不再存储数据,数据只存储在同一层的叶子节点上,B + 树从根到每一个节点的路径长度一样,而 B 树不是这样。叶子之间,增加了链表 (图中红色箭头指向),获取所有节点,不再需要中序遍历,使用链表的 next 节点就可以快速访问到。范围查找方面,当定位 min 与 max 之后,中间叶子节点,就是结果集,不用中序回溯(范围查询在 SQL 中用得很多,这是 B + 树比 B 树最大的优势)。叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;非叶子节点存储记录的 PK,用于查询加速,适合内存存储。非叶子节点,不存储实际记录,而只存储记录的 KEY 的话,那么在相同内存的情况下,B + 树能够存储更多索引。B + 树好处总结:查询任何一条记录速度是比较平均的,不会出现效率差异大的情况。不需要进行额外的中序遍历了。遍历链表就是得到中序结果。处理范围查找就更高效了。叶子放到磁盘上,非叶子放到内存中。查找效率就更高了 (减少了读磁盘的次数)。索引在内存中占用的实际开销也不高。

B-Tree 索引的适用场景广泛,全值匹配、最左前缀、匹配列前缀、匹配范围值、精确匹配某一列并范围匹配另外一列以及只访问索引的查询都可以使用 B-Tree 索引。例如,全值匹配指的是和索引中的所有列进行匹配,即可用于查找姓名和出生日期匹配。最左前缀如只查找姓,即只使用索引的第一列。匹配列前缀也可以只匹配某一列值的开头部分,如匹配以 J 开头的姓的人,这里也只是使用了索引的第一列,且是第一列的一部分。匹配范围值如查找姓在 allen 和 barrymore 之间的人,这里也只使用了索引的第一列。精确匹配某一列并范围匹配另外一列如查找所有姓为 allen,并且名字字母是 K 开头的,即,第一列 last_name 精确匹配,第二列 first_name 范围匹配。只访问索引的查询即查询只需要访问索引,而无需访问数据行,即,这个就是覆盖索引的概念。需要访问的数据直接从索引中取得。为索引树中的节点是有序的,所以除了按值查找之外,索引还可以用于查询中的 order by 操作,一般来说,如果 btree 可以按照某种方式查找的值,那么也可以按照这种方式用于排序,所以,如果 order by 子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求。

  1. 哈希索引:适用于等值查询,但不支持范围查询。

哈希索引(hash index)基于哈希表实现。MySQL 目前仅有 MEMORY 存储引擎和 HEAP 存储引擎支持这类索引。其中,MEMORY 存储引擎可以支持 B - 树索引和 HASH 索引,且将 HASH 当成默认索引。哈希索引的最大特点是访问速度快,但也存在一些缺点。MySQL 需要读取表中索引列的值来参与散列计算,散列计算是一个比较耗时的操作。也就是说,相对于 B - 树索引来说,建立哈希索引会耗费更多的时间。不能使用 HASH 索引排序。HASH 索引只支持等值比较,如 “=”“IN ()” 或 “<=”(安全等于,select null <= null 和 select null=null 是不一样的结果)。哈希索引的性能跟哈希冲突数量成反比,哈希冲突越多其维护代价越大性能越低。Hash 碰撞通用的处理方法是使用链表,将 Hash 冲突碰撞的元素形成一个链表,发生冲突时在链表上进行二次遍历找到数据。Hash 碰撞跟选择的 Hash 算法有关系,为了减少 Hash 碰撞的概率,优先选择避免 Hash 冲突的 Hash 算法,例如,使用 Percona Server 的函数 FNV64 (),其哈希值为 64 位,出现 Hash 冲突的概率要比 CRC32 小很多。

InnoDB 自适应哈希索引是为了提升查询效率,InnoDB 存储引擎会监控表上各个索引页的查询,当 InnoDB 注意到某些索引值访问非常频繁时,会在内存中基于 B+Tree 索引再创建一个哈希索引,使得内存中的 B+Tree 索引具备哈希索引的功能,即能够快速定值访问频繁访问的索引页。

在使用 InnoBD 引擎时,我们可以在 B-Tree 的基础上创建一个伪哈希索引。当然这不是真正的哈希索引,因为还是使用的 B-Tree 进行查找,但它使用哈希值而不是键本身进行索引查找。例如,如果需要存储大量的 URL 并且需要根据 URL 进行查找,如果使用 B-Tree 来存储 URL,则存储的内容就会很大,因为 URL 本身就很长。为此,我们可以单独指定一个哈希列并为该列创建索引,并选择一个哈希函数!每次存储、变更 URL 时,对该 URL 应用一个函数计算出一个哈希值,存入对应的哈希列中。在查询时,如果采用体积很小的基于哈希值的索引来查找,则性能会提升很多,唯一的缺点就是需要调用一个哈希函数,为此我们可以使用触发器来实现。如果出现了哈希冲突,则查询会返回多行数据,为此在查询时还必须带上真正的 URL 常量值。正确的查询语句为:select xx from url where url_hash =hash ('https://www.baidu.com/')AND url ='https://www.baidu.com/';

  1. 全文索引:用于全文搜索。

全文索引是一种特殊类型索引,用于查找文本中的关键词,而不是直接比较是否相等。全文索引的和其他索引的匹配方式完全不一样,全文索引更类似于搜索引擎做的事情,查找条件使用 MATCH AGAINST,而不是普通的 WHERE。全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。MyISAM 存储引擎支持全文索引,InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。

全文检索通常使用倒排索引(inverted index)来实现,倒排索引同 B+Tree 一样,也是一种索引结构。它在辅助表中存储了单词与单词自身在一个或多个文档中所在位置之间的映射,这通常利用关联数组实现,拥有两种表现形式:inverted file index:{单词,单词所在文档的 id};full inverted index:{单词,(单词所在文档的 id,再具体文档中的位置)}。

全文索引带来的负面影响:占有存储空间更大,如果内存一次装不下全部索引,性能会非常差。增删改代价更大,修改文本中 10 个单词,则要操作维护索引 10 次,而不是普通索引的一次。如果一个列上有全文索引则一定会用上,即使有性能更好的其他索引也不会用上。由于只是存储文档指针,也就用不上索引覆盖。

  1. 空间索引:用于地理空间数据。

MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。必须使用 GIS 相关的函数来维护数据。

三、索引的设计原则

(一)选择合适的索引类型

索引类型的选择应根据具体的查询需求来决定。例如,如果查询需求主要是范围查询和排序操作,那么 B-Tree 索引是一个合适的选择。B-Tree 索引不再是二叉搜索,而是 N 叉搜索,树的高度会降低,查询速度快。叶子节点和非叶子节点都可以存储数据,且可以存储多个数据。通过中序遍历,可以访问树上所有节点。同时,B-Tree 索引适用于全值匹配、最左前缀、匹配列前缀、匹配范围值、精确匹配某一列并范围匹配另外一列以及只访问索引的查询等多种情况。

如果查询需求主要是等值查询,哈希索引可能是一个选择。哈希索引基于哈希表实现,访问速度快,但不支持范围查询。MySQL 目前仅有 MEMORY 存储引擎和 HEAP 存储引擎支持这类索引。哈希索引的性能跟哈希冲突数量成反比,哈希冲突越多其维护代价越大性能越低。为了减少哈希冲突的概率,可以优先选择避免哈希冲突的哈希算法。

然而,选择索引类型时也需要考虑其缺点。例如,B-Tree 索引在插入、更新和删除操作时需要更新索引结构,可能会导致性能下降。哈希索引不能使用哈希索引排序,只支持等值比较,且哈希冲突可能会影响性能。

(二)索引字段的选择

索引字段的选择对于提高查询效率至关重要。应选择高选择性的字段作为索引,即字段值的唯一性较高的字段。这样的字段可以显著减少数据扫描的数量,从而提高查询性能。例如,如果一个表中有多个字段,其中一个字段的取值范围很广,而另一个字段的取值范围很窄,那么选择取值范围广的字段作为索引可能会更有效。

在设计 MySQL 索引时,需要综合考虑多个因素。数据量大小、联接操作、查询条件、选择性和重复度、字段大小、复合索引、索引的维护成本、排序和分组等因素都可能影响索引的选择。例如,对于频繁参与 JOIN 操作的列上创建索引可以显著提高联接查询的效率;经常出现在 WHERE 子句中的字段是索引的理想候选者;索引应该尽量建立在小的字段上,因为索引本身也需要存储空间,并且索引的维护也会消耗资源。

总之,选择合适的索引类型和字段是 MySQL 索引优化的关键,需要根据具体的查询需求和数据特点进行综合考虑。

四、索引优化技巧

(一)选择合适的索引列

在 MySQL 中,为经常出现在 WHERE 子句、ORDER BY 子句以及 JOIN 操作中的列创建索引是一种有效的优化策略。例如,如果有一个用户表,经常根据用户的年龄进行查询和排序,那么为年龄列创建索引将大大提高查询性能。CREATE INDEX idx_age ON users (age); 如果在多个表的连接操作中,某个表的特定列经常被用于连接条件,也应该为该列创建索引,以提高连接操作的效率。

(二)使用复合索引

当查询条件同时涉及多个列时,复合索引可显著提高查询性能。复合索引是将多个字段作为一个索引来创建,可以为多个列提供索引。例如,一个用户表中有 id、username、age、sex、email 等字段,如果同时需要根据 age 和 sex 字段来进行查询,可以创建一个复合索引:CREATE INDEX age_sex_index ON user (age,sex); 这样,查询 age=18 and sex='male' 的数据时,数据库就会先按照 age 字段排列,然后在这个分组中按照 sex 字段进行排列,最终得到我们需要的数据。在选择复合索引字段时,应选择重要的字段,且字段数量尽量少,一般不超过 3 个,并遵循最左匹配原则,同时考虑字段类型。

(三)避免全表扫描

全表扫描是性能杀手。通过 EXPLAIN 关键字可以分析查询是否进行了全表扫描,并据此优化索引。例如:使用 EXPLAIN 分析查询:EXPLAIN SELECT * FROM users WHERE age > 30; 如果发现查询没有使用索引而是进行了全表扫描,那么可能需要为相关列添加索引。对于小表,表扫描通常是适当的,对性能的影响可以忽略不计。对于大表,可以尝试使用 ANALYZE TABLE tbl_name 更新扫描表的键分布,对被扫描的表使用 FORCE INDEX,或者启动 mysqld 时使用 --max-seeks-for-key=1000 选项等技术来避免优化器错误地选择表扫描。

(四)删除冗余和不必要的索引

多余索引会占用空间并影响写入操作,定期审查删除是一个好习惯。过多的索引降低了写入数据的效率,因为在写入数据时需要更新索引,这样需要花很多的时间。同时,太多的索引增加了查询优化器的选择时间。不合理的使用索引,会大幅占用磁盘空间。系统在线上运行一段时候后,可以使用这条 sql 语句来查看索引的使用情况,0 代表索引从来没有被使用过,可以考虑进行删除。SELECT object_type,object_schema,object_name,index_name,count_read,count_fetch, count_insert,count_update,count_delete FROM performance_schema.table_io_waits_summary_by_index_usage ORDER BY sum_timer_wait desc;

(五)使用覆盖索引

查询只通过索引获取数据,无需回表查询,可提高性能。例如,如果经常查询用户的 name 和 email,可以创建一个包含这两列的复合索引。CREATE INDEX idx_name_email ON users (name, email); 当执行如下查询时,由于所需数据都在索引中,因此无需回表查询。SELECT name, email FROM users WHERE name = 'John Doe'; 覆盖索引的使用能够减少树的搜索次数,避免了回表,显著提升了查询性能。

(六)优化索引长度

对于 VARCHAR 等类型的列,可指定索引前缀长度减少大小提高效率。为 name 字段的前 10 个字符创建索引。CREATE INDEX idx_name_prefix ON users (name (10)); 但需要注意的是,这可能会影响到索引的选择性和查询性能。

(七)定期维护索引

使用 OPTIMIZE TABLE 命令重新组织表和索引,提高性能。随着时间的推移,数据库的使用和数据的变化可能会导致索引碎片化。定期使用 OPTIMIZE TABLE 命令可以帮助重新组织表和索引,提高性能。例如:优化 users 表及其索引。OPTIMIZE TABLE users;

五、分页查询优化

(一)根据自增且连续的主键排序的分页查询

可通过主键查询替代 LIMIT 分页,提高效率,但需满足主键自增且连续且结果按主键排序。例如在某些业务场景中,如果我们有一个表的主键是自增且连续的,并且查询结果是按照主键进行排序的,那么可以使用以下方式进行分页查询。原本可能使用select * from table limit offset, limit这样的语句,现在可以改为select * from table where id > offset limit limit。这样的改写能够利用主键索引,从指定的位置开始扫描,而不是像 LIMIT 分页那样先读取大量不需要的数据再进行筛选,从而大大提高查询效率。但是这种方式在很多场景并不实用,因为如果表中某些记录被删除后,主键可能会出现空缺,导致结果不一致。

(二)根据非主键字段排序的分页查询

使用覆盖索引优化,先查出主键再根据主键查记录,提高效率。当我们按照非主键字段进行排序分页查询时,直接使用 LIMIT 可能会导致效率低下。这是因为 MySQL 在处理这种查询时,可能会放弃使用索引而进行全表扫描。为了解决这个问题,可以采用覆盖索引的方法进行优化。具体来说,先通过对非主键字段进行排序查询出主键,然后再根据主键查询出完整的记录。例如,对于一个按照name字段排序的分页查询select * from employees ORDER BY name limit offset, limit,可以改写成select * from employees e inner join (select id from employees order by name limit offset, limit) ed on e.id = ed.id。这样的查询方式先在子查询中查询出符合条件的主键,然后通过连接查询根据主键获取完整的记录。这种方式可以减少回表操作,提高查询效率。同时,执行时间相比直接使用 LIMIT 分页会减少一半以上。通过对比优化前后的 SQL 执行计划可以发现,原 SQL 使用的是文件排序(filesort),而优化后的 SQL 使用的是索引排序。

六、Join 关联查询优化

(一)Nested-Loop Join 算法

在 MySQL 中,Join 关联查询优化至关重要,其中 Nested-Loop Join 算法是一种常用的连接算法。Nested-Loop Join 翻译成中文是 “嵌套循环连接”。例如,当执行select * from t1 inner join t2 on t1.id=t2.tid时,t1 称为外层表,也可称为驱动表;t2 称为内层表,也可称为被驱动表。

MySQL 的 Nested-Loop Join 有三种实现的算法:Simple Nested-Loop Join、Index Nested-Loop Join 和 Block Nested-Loop Join。

Simple Nested-Loop Join 简单粗暴,就是一个双层 for 循环,通过循环外层表的行数据,逐个与内层表的所有行数据进行比较来获取结果。如果每个表有 1 万条数据,那么对数据比较的次数就会达到 1 亿次,查询效率非常慢。

Index Nested-Loop Join 是通过外层表匹配条件直接与内层表索引进行匹配,避免和内层表的每条记录去进行比较,极大地减少了对内层表的匹配次数。从原来的匹配次数 = 外层表行数 * 内层表行数,变成了外层表的行数 * 内层表索引的高度,极大地提升了 join 的性能。使用 Index Nested-Loop Join 算法的前提是匹配的字段,在被驱动表(内表)上必须建立了索引。

Block Nested-Loop Join 通过一次性缓存多条数据,把参与查询的列缓存到 Join Buffer 里,然后拿 join buffer 里的数据批量与内层表的数据进行匹配,从而减少了内层循环的次数。当不使用 Index Nested-Loop Join 的时候,默认使用 Block Nested-Loop Join。Join Buffer 会缓存所有参与查询的列而不是只有 Join 的列,可以通过调整 join_buffer_size 缓存大小,其默认值是 256K。使用 Block Nested-Loop Join 算法需要开启优化器管理配置的 optimizer_switch 的设置 block_nested_loop 为 on,默认为开启。

在选择 Join 算法时,会有优先级,理论上会优先判断能否使用 Index Nested-Loop Join、Block Nested-Loop Join:Index Nested-Loop Join > Block Nested-Loop Join > Simple Nested-Loop Join。优化 Join 速度的方法有:用小结果集驱动大结果集,减少外层循环的数据量;为匹配的条件增加索引;增大 join buffer size 的大小;减少不必要的字段查询。

七、其他提升查询效率的方法

(一)使用索引

合理创建索引是提升查询效率的重要手段之一。索引可以加快数据的检索速度,避免全表扫描。在 MySQL 中,可以根据具体的查询需求选择不同类型的索引,如 B-Tree 索引、哈希索引、全文索引和空间索引等。不同类型的索引适用于不同的查询场景,合理选择索引类型可以显著提高查询性能。

(二)优化查询语句

在编写查询语句时,应避免使用 SELECT *,这样可以减少返回的数据量,提高查询效率。同时,合理使用 WHERE 子句可以精确筛选出需要的数据,避免不必要的数据检索。例如,在查询条件中使用合适的运算符和函数,可以提高查询的准确性和效率。

(三)限制返回的结果集大小

使用 LIMIT 可以限制查询返回的数据量,避免返回大量不必要的数据。这对于处理大型数据集非常有用,可以减少网络传输和内存消耗。例如,在分页查询中,可以使用 LIMIT 结合 OFFSET 来实现分页功能,每次只返回指定数量的记录。

(四)批量插入和更新

采用批量插入和更新的方式可以减少与数据库的交互次数,提高数据操作的效率。例如,可以使用 INSERT INTO... VALUES 和 UPDATE... SET 等语句进行批量操作,而不是逐个插入或更新数据。这样可以减少数据库的开销,提高数据处理的速度。

(五)避免使用 SELECT COUNT(*)

在需要获取行数的情况下,可以使用其他方式进行估算或使用缓存机制,避免使用 SELECT COUNT(*)。因为 SELECT COUNT(*) 通常会进行全表扫描,效率较低。可以通过维护一个计数器或者使用近似估算的方法来获取行数信息。

(六)定期优化数据库表

使用 OPTIMIZE TABLE 命令可以定期优化数据库表,压缩空间并提高查询性能。随着时间的推移,数据库表可能会出现碎片,影响查询效率。通过执行 OPTIMIZE TABLE 命令,可以重新组织表和索引,消除碎片,提高数据库的性能。

(七)使用连接池

通过使用连接池管理数据库连接,可以避免频繁地创建和销毁连接,提高数据库操作的效率。连接池可以重复使用已经建立的连接,减少连接建立的时间和资源消耗。在高并发的应用场景下,连接池可以显著提高数据库的性能和响应速度。

(八)避免使用过多的触发器和存储过程

过多的触发器和存储过程会增加数据库的负担,影响性能。在设计数据库时,应合理评估使用触发器和存储过程的必要性。如果可以通过其他方式实现相同的功能,应尽量避免使用触发器和存储过程。同时,过多的触发器和存储过程也会增加数据库的维护难度。

(九)合理使用缓存

使用缓存技术可以减少对数据库的频繁访问,提高响应速度。可以使用缓存工具如 Redis 等缓存经常使用的数据,避免重复查询数据库。在应用程序中,可以将查询结果缓存起来,下次需要相同数据时直接从缓存中获取,而不是再次查询数据库。

(十)定期备份和优化数据库

定期备份数据库可以防止数据丢失,同时定期进行数据库优化操作,如清理无用数据、重建索引等,可以保持数据库的健康状态。通过定期备份和优化,可以提高数据库的性能和稳定性,确保数据库的正常运行。

八、结论

索引优化是数据库性能调优的重要组成部分,通过多种技巧可显著提升 MySQL 查询性能,但需综合考虑各种因素,避免过度或不当使用索引。

在实际应用中,我们需要根据具体的业务需求和数据特点来选择合适的索引优化策略。例如,对于查询频繁的字段创建合适的索引类型,如 B-Tree 索引适用于大多数场景,哈希索引适用于等值查询等。同时,要注意索引的设计原则,选择高选择性的字段作为索引,避免创建过多的冗余索引。

在进行分页查询和 Join 关联查询时,也可以采用特定的优化技巧来提高查询效率。例如,在分页查询中,可以根据主键是否自增且连续选择不同的优化方式;在 Join 关联查询中,根据不同的情况选择合适的 Nested-Loop Join 算法。

此外,还可以通过其他方法提升查询效率,如合理使用索引、优化查询语句、限制返回结果集大小、批量插入和更新、避免使用特定的查询方式、定期优化数据库表、使用连接池、避免过多的触发器和存储过程以及合理使用缓存等。

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

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

相关文章

selenium 在已打开浏览器上继续调试

关闭浏览器&#xff0c;终端执行如下指令&#xff0c;--user-data-dir换成自己的User Data路径 chrome.exe --remote-debugging-port9222 --user-data-dir"C:\Users\xxx\AppData\Local\Google\Chrome\User Data" 会打开浏览器&#xff0c;打开百度&#xff0c;如下状…

Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架

Pytest-Bdd vs Behave&#xff1a;选择最适合的 Python BDD 框架 Pytest BDD vs Behave&#xff1a;选择最适合的 Python BDD 框架BDD 介绍Python BDD 框架列表Python BehavePytest BDDPytest BDD vs Behave&#xff1a;关键区别Pytest BDD vs Behave&#xff1a;最佳应用场景结…

B站bilibili视频转文字字幕下载方法

本文将讲述介绍一种使用本地工具如何快速的下载B站的字幕为本地文本文件的方法。 通常获取B站字幕需要在浏览器中安装第三方插件&#xff0c;通过插件获取字幕。随着大模型&#xff0c;生成式AI&#xff0c;ChatGPT的应用&#xff0c;B站也提供了AI小助手对视频的内容进行总结…

ElasticSearch的自动补全功能(拼音分词器、自定义分词器、DSL实现自动补全查询、RestAPI实现自动补全查询)

文章目录 1. 什么是自动补全2. 拼音分词器2.1 初识拼音分词器2.2 下载拼音分词器2.3 安装拼音分词器2.4 测试拼音分词器 3. 自定义分词器3.1 拼音分词器存在的问题3.2 分词器&#xff08;analyzer&#xff09;的组成3.3 如何自定义分词器3.4 拼音分词器的可选参数3.5 配置自定义…

day12 接口测试 ——入门→精通→实战(1)

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、接口测试分类 1.1 内部接口&#xff1a; 1.2 外部接口&#xff1a; 2、目前接口架构设计 2.1、基于SOAP架构&#xff0c; 2.2、基于RPC架构&#xff0c; 2.3、基于RestFul架构&#xff0c; 2.3.1…

54、库卡机器人轴的软限位设置

步骤1&#xff1a;将用户组改为“专家”。 步骤2&#xff1a;点击“投入运行”----“售后服务”-----“软件限位开关” 步骤3&#xff1a;就可以针对每个轴修改对应的角度值&#xff0c;然后点击“保存”。

PHP+MySQL 学生信息管理系统

目录 MySQL建表指令 主页面展示 主页面源代码如下 增&#xff1a;添加学生信息 添加html如下 html&#xff1a;主要用于显示网页内容 成功添加后回显 ​编辑 增加php如下 删&#xff1a;删除学生信息 删除html如下 成功删除后回显 删除php如下 改&#xff1a;修改学…

【第三节】Git 基本操作指南

目录 前言 一、获取与创建项目 1.1 git init 1.2 git clone 二、基本快照操作 2.1 git add 2.2 git status 2.3 git diff 2.4 git commit 2.5 git reset HEAD 三、 文件管理 3.1 git rm 3.2 git mv 四、Git 文件状态 5.1 工作目录 5.2 暂存区 5.3 本地仓库 5…

【第六节】Git Flow:分支管理模型与工作流程

一、Git Flow 简介 1.1 什么是 Git Flow Git Flow 是一种基于 Git 的分支管理模型&#xff0c;旨在帮助团队更好地管理和发布软件。它由 Vincent Driessen 在 2010 年提出&#xff0c;通过一套标准的分支命名和工作流程&#xff0c;使开发、测试和发布过程更加有序和高效。不过…

Windows 与 Linux 下 Ping IPv6 地址 | 常用网络命令

注&#xff1a;本文为网络命令相关文章合辑。 未整理去重。 一、IPv6 概述 IPv6 即 “Internet 协议版本 6”&#xff0c;因 IPv4 地址资源面临耗尽问题而被引入以替代 IPv4。IPv6 则提供了理论上多达 2 128 2^{128} 2128 个地址&#xff0c;有效解决地址不足困境。 IPv6 具…

GB28181系列三:GB28181流媒体服务器ZLMediaKit

我的音视频/流媒体开源项目(github) GB28181系列目录 目录 一、ZLMediaKit介绍 二、 ZLMediaKit安装、运行(Ubuntu) 1、安装 2、运行 3、配置 三、ZLMediaKit使用 一、ZLMediaKit介绍 ZLMediaKit是一个基于C11的高性能运营级流媒体服务框架&#xff0c;项目地址&#xf…

【深度学习】深刻理解Swin Transformer

Swin Transformer 是一种基于 Transformer 的视觉模型&#xff0c;由 Microsoft 研究团队提出&#xff0c;旨在解决传统 Transformer 模型在计算机视觉任务中的高计算复杂度问题。其全称是 Shifted Window Transformer&#xff0c;通过引入分层架构和滑动窗口机制&#xff0c;S…

uniCloud云开发视频教程-从基础入门到项目开发实战-uniapp进阶课文章管理系统(云函数/云数据库/云存储)

大家好&#xff0c;我是爱搞知识的咸虾米。 今天给大家带来一门uniCloud基础入门到项目开发实战的课程。 视频学习地址&#xff1a;https://www.bilibili.com/video/BV1PP411E7qG/ 开始学习这门课之前&#xff0c;最好先学习一下uniapp零基础入门这套课&#xff0c;相信很多同…

GLB格式转换为STL格式

GLB与STL格式简介 GLB格式 GLB代表“GL传输格式二进制文件”&#xff08;GL Transmission Format Binary&#xff09;。GLB主要用于共享3D数据&#xff0c;包含三维模型、场景、光源、材质、节点层次和动画等详细信息&#xff0c;是一种标准化的文件格式&#xff0c;适用于多…

Qt编译MySQL数据库驱动

目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 &#xff08;1&#xff09;先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 &#xff08;2&#xff09;在D:\qt\5.12.12\Src\qtbase\src\plugins\sqldrivers\mysql下…

MySQL通过binlog日志进行数据恢复

记录一次阿里云MySQL通过binlog日志进行数据回滚 问题描述由于阿里云远程mysql没有做安全策略 所以服务器被别人远程攻击把数据库给删除&#xff0c;通过查看binlog日志可以看到进行了drop操作&#xff0c;下面将演示通过binlog日志进行数据回滚操作。 1、查询是否开始binlog …

如何在 Ubuntu 22.04 上安装和使用 Rust 编程语言环境

简介 Rust 是一门由 Mozilla 开发的系统编程语言&#xff0c;专注于性能、可靠性和内存安全。它在没有垃圾收集的情况下实现了内存安全&#xff0c;这使其成为构建对性能要求苛刻的应用程序&#xff08;如操作系统、游戏引擎和嵌入式系统&#xff09;的理想选择。 接下来&…

前端项目初始化搭建(二)

一、使用 Vite 创建 Vue 3 TypeScript 项目 PS E:\web\cursor-project\web> npm create vitelatest yf-blog -- --template vue-ts> npx > create-vite yf-blog --template vue-tsScaffolding project in E:\web\cursor-project\web\yf-blog...Done. Now run:cd yf-…

生活小妙招之UE CaptureRT改

需求&#xff0c;四个不同的相机拍摄结果同屏分屏显示 一般的想法是四个Capture拍四张RT&#xff0c;然后最后在面片/UI上组合。这样的开销是创建4张RT&#xff0c;材质中采样4次RT。 以更省的角度&#xff0c;想要对以上流程做优化&#xff0c;4个相机拍摄是必须的&#xff…

【AIGC进阶-ChatGPT提示词副业解析】探索生活的小确幸:在平凡中寻找幸福

引言 在这个快节奏的现代社会中,我们常常被各种压力和焦虑所困扰,忘记了生活中那些细小而珍贵的幸福时刻。本文将探讨如何在日常生活中发现和珍惜那些"小确幸",以及如何通过尝试新事物来丰富我们的生活体验。我们还将讨论保持神秘感和期待感对于维持生活乐趣的重要性…