03.PostgreSQL常用索引与优化

PostgreSQL常用索引与优化

主要内容转载自《PostgreSQL 开发指南》

索引(Index)可以用于提高数据库的查询性能;但是索引也需要进行读写,同时还会占用更多的存储空间;因此了解并适当利用索引对于数据库的优化至关重要。本篇我们就来介绍如何高效地使用 PostgreSQL 索引。

索引简介

假设存在以下数据表:

CREATE TABLE test (id integer,name text
);insert into test
select v,'val:'||v from generate_series(1, 10000000) v;

我们经常需要使用类似以下的查询返回结果:

SELECT name FROM test WHERE id = 10000;

如果没有索引,数据库需要扫描整个表才能找到相应的数据。利用EXPLAIN命令可以看到数据库的执行计划,也就是 PostgreSQL 执行 SQL 语句的具体步骤:

explain analyze
SELECT name FROM test WHERE id = 10000;
QUERY PLAN                                                                                                              |
------------------------------------------------------------------------------------------------------------------------|
Gather  (cost=1000.00..107137.70 rows=1 width=11) (actual time=50.266..12082.777 rows=1 loops=1)                        |Workers Planned: 2                                                                                                    |Workers Launched: 2                                                                                                   |->  Parallel Seq Scan on test  (cost=0.00..106137.60 rows=1 width=11) (actual time=7674.992..11553.964 rows=0 loops=3)|Filter: (id = 10000)                                                                                            |Rows Removed by Filter: 3333333                                                                                 |
Planning Time: 16.480 ms                                                                                                |
Execution Time: 12093.016 ms                                                                                            |

Parallel Seq Scan 表示并行顺序扫描,执行消耗了 12 s;由于表中有包含大量数据,而查询只返回一行数据,显然这种方法效率很低。

关于执行计划的更多信息,可以参考这篇文章。

此时,如果在 id 列上存在索引,则可以通过索引快速找到匹配的结果。我们先创建一个索引:

CREATE INDEX test_id_index ON test (id);

创建索引需要消耗一定的时间。然后再次查看数据库的执行计划:

explain analyze
SELECT name FROM test WHERE id = 10000;
QUERY PLAN                                                                                                           |
---------------------------------------------------------------------------------------------------------------------|
Index Scan using test_id_index on test  (cost=0.43..8.45 rows=1 width=11) (actual time=20.410..20.412 rows=1 loops=1)|Index Cond: (id = 10000)                                                                                           |
Planning Time: 14.989 ms                                                                                             |
Execution Time: 20.521 ms                                                                                            |

Index Scan 表示索引扫描,执行消耗了 20 ms;这种方式类似于图书最后的关键字索引,读者可以相对快速地浏览索引并翻到适当的页面,而不必阅读整本书来找到感兴趣的内容。

索引不仅仅能够优化查询语句,某些包含WHERE条件的UPDATEDELETE语句也可以利用索引提高性能,因为修改数据的前提是找到数据。

此外,索引也可以用于优化连接查询,基于连接条件中的字段创建索引可以提高连接查询的性能。索引甚至还能优化分组或者排序操作,因为索引自身是按照顺序进行组织存储的。

另一方面,系统维护索引需要付出一定的代价,从而增加数据修改操作的负担。所以,我们需要合理创建索引,一般只为经常使用到的字段创建索引。就像图书一样,不可能为书中的每个关键字都创建一个索引。

索引类型

详细介绍可参考: PostgreSQL 9种索引的原理和应用场景

PostgreSQL 提高了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN 等索引。每种索引基于不同的存储结构和算法,用于优化不同类型的查询。默认情况下,PostgreSQL 创建 B-树索引,因为它适合大部分情况下的查询。

1.B-树索引

注意B树就是B-树,"-"是个连字符号,不是减号。
B-树是一种平衡的多路**查找(又称排序)**树,在文件系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance),与B+树区别可参考:https://xiaolincoding.com/mysql/index/why_index_chose_bpuls_tree.html#_3%E3%80%81%E8%8C%83%E5%9B%B4%E6%9F%A5%E8%AF%A2

实现原理可参考:《深入浅出PostgreSQL B-Tree索引结构》

B-树是一个自平衡树(self-balancing tree),按照顺序存储数据,支持对数时间复杂度(O(logN))的搜索、插入、删除和顺序访问。举例来说,假如 100 条数据时需要 1 次磁盘 I/O,也就是说 N 等于 100;10000 条数据时只需要 2 次 I/O,1 亿数据时只需要 4 次 I/O。

对于索引列上的以下比较运算符,PostgreSQL 优化器都会考虑使用 B-树索引:

  • <
  • <=
  • =
  • >=
  • BETWEEN
  • IN
  • IS NULL
  • IS NOT NULL

另外,如果模式匹配运算符LIKE~中模式的开头不是通配符,优化器也可以使用 B-树索引,例如:

col  LIKE 'foo%' 
col  ~ '^foo'

对于不区分大小的的ILIKE~*运算符,如果匹配的模式以非字母的字符(不受大小写转换影响)开头,也可以使用 B-树索引。

B-树索引还可以用于优化排序操作,例如:

SELECT col1, col2FROM tWHERE col1 BETWEEN 100 AND 200ORDER BY col1;

col1 上的索引不仅能够优化查询条件,也可以避免额外的排序操作;因为基于该索引访问时本身就是按照排序返回结果。

2.哈希索引

哈希索引(Hash index)只能用于简单的等值查找(=),也就是说索引字段被用于等号条件判断。因为对数据进行哈希运算之后不再保留原来的大小关系。

hash索引特别适用于字段VALUE非常长(不适合b-tree索引,因为b-tree一个PAGE至少要存储3个ENTRY,所以不支持特别长的VALUE)的场景,例如很长的字符串,并且用户只需要等值搜索,建议使用hash index。

创建哈希索引需要使用HASH关键字:

CREATE INDEX index_name 
ON table_name USING HASH (column_name);

CREATE INDEX语句用于创建索引,USING子句指定索引的类型,具体参考下文。

3.GiST 索引

GiST 代表通用搜索树(Generalized Search Tree),GiST 索引单个索引类型,而是一种支持不同索引策略的框架。GiST 索引常见的用途包括几何数据的索引和全文搜索。GiST 索引也可以用于优化“最近邻”搜索,例如:

SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;

该语句用于查找距离某个目标地点最近的 10 个地方。

GiST是一个通用的索引接口,可以使用GiST实现b-tree, r-tree等索引结构。

不同的类型,支持的索引检索也各不一样。例如:

1、几何类型,支持位置搜索(包含、相交、在上下左右等),按距离排序。

2、范围类型,支持位置搜索(包含、相交、在左右等)。

3、IP类型,支持位置搜索(包含、相交、在左右等)。

4、空间类型(PostGIS),支持位置搜索(包含、相交、在上下左右等),按距离排序。

5、标量类型,支持按距离排序。

实现原理可参考:《PostgreSQL 百亿地理位置数据 近邻查询性能》

4.SP-GiST 索引

SP-GiST 代表空间分区 GiST,主要用于 GIS、多媒体、电话路由以及 IP 路由等数据的索引。

与 GiST 类似,SP-GiST 也支持“最近邻”搜索。是一个通用的索引接口,但是SP-GIST使用了空间分区的方法,使得SP-GiST可以更好的支持非平衡数据结构,例如quad-trees, k-d tree, radis tree.

实现原理可参考:《Space-partitioning trees in PostgreSQL》

5.GIN 索引

GIN 代表广义倒排索引(generalized inverted indexes),主要用于单个字段中包含多个值的数据,例如 hstore、array、jsonb 以及 range 数据类型。一个倒排索引为每个元素值都创建一个单独的索引项,可以有效地查询某个特定元素值是否存在。Google、百度这种搜索引擎利用的就是倒排索引。

实现原理可参考:《PostgreSQL GIN索引实现原理》

应用场景

1、当需要搜索多值类型内的VALUE时,适合多值类型,例如数组、全文检索、TOKEN。(根据不同的类型,支持相交、包含、大于、在左边、在右边等搜索)

2、当用户的数据比较稀疏时,如果要搜索某个VALUE的值,可以适应btree_gin支持普通btree支持的类型。(支持btree的操作符)

3、当用户需要按任意列进行搜索时,gin支持多列展开单独建立索引域,同时支持内部多域索引的bitmapAnd, bitmapOr合并,快速的返回按任意列搜索请求的数据。

6.BRIN 索引

BRIN 代表块区间索引(block range indexes),存储了连续物理范围区间内的数据摘要信息。BRIN 也相比于 B-树索引要小很多,维护也更容易。对于不进行水平分区就无法使用 B-树索引的超大型表,可以考虑 BRIN。

BRIN 通常用于具有线性排序顺序的字段,例如订单表的创建日期。

例如时序数据,在时间或序列字段创建BRIN索引,进行等值、范围查询时效果很棒。

应用场景

《BRIN (block range index) index》

《PostgreSQL 物联网黑科技 - 瘦身几百倍的索引(BRIN index)》

《PostgreSQL 聚集存储 与 BRIN索引 - 高并发行为、轨迹类大吞吐数据查询场景解说》

《PostgreSQL 并行写入堆表,如何保证时序线性存储 - BRIN索引优化》

7.rum 索引

原理可参考:https://github.com/postgrespro/rum

rum 是一个索引插件,由Postgrespro开源,适合全文检索,属于GIN的增强版本。

增强包括:

1、在RUM索引中,存储了lexem的位置信息,所以在计算ranking时,不需要回表查询(而GIN需要回表查询)。

2、RUM支持phrase搜索,而GIN无法支持。

3、在一个RUM索引中,允许用户在posting tree中存储除ctid(行号)以外的字段VALUE,例如时间戳。

这使得RUM不仅支持GIN支持的全文检索,还支持计算文本的相似度值,按相似度排序等。同时支持位置匹配,例如(速度与激情,可以采用"速度" <2> “激情” 进行匹配,而GIN索引则无法做到)

应用场景

《PostgreSQL 全文检索加速 快到没有朋友 - RUM索引接口(潘多拉魔盒)》

《从难缠的模糊查询聊开 - PostgreSQL独门绝招之一 GIN , GiST , SP-GiST , RUM 索引原理与技术背景》

《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 3 rum, smlar应用场景分析》

8.bloom 索引

bloom索引接口是PostgreSQL基于bloom filter构造的一个索引接口,属于lossy索引,可以收敛结果集(排除绝对不满足条件的结果,剩余的结果里再挑选满足条件的结果),因此需要二次check,bloom支持任意列组合的等值查询。

bloom存储的是签名,签名越大,耗费的空间越多,但是排除更加精准。有利有弊。

CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3)WITH (length=80, col1=2, col2=2, col3=4);签名长度 80 bit, 最大允许4096 bits
col1 - col32,分别指定每列的bits,默认长度2,最大允许4095 bits.

应用场景

bloom索引适合多列任意组合查询。

《PostgreSQL 9.6 黑科技 bloom 算法索引,一个索引支撑任意列组合查询》

9.zombodb 索引

zombodb是PostgreSQL与ElasticSearch结合的一个索引接口,可以直接读写ES。

https://github.com/zombodb/zombodb

应用场景

与ES结合,实现SQL接口的搜索引擎,实现数据的透明搜索。

创建索引

PostgreSQL 使用CREATE INDEX语句创建新的索引:

CREATE INDEX index_name ON table_name 
[USING method]
(column_name [ASC | DESC] [NULLS FIRST | NULLS LAST]);

其中:

  • index_name 是索引的名称,table_name 是表的名称;
  • method 表示索引的类型,例如 btree、hash、gist、spgist、gin 或者 brin。默认为 btree
  • column_name 是字段名,ASC表示升序排序(默认值),DESC表示降序索引;
  • NULLS FIRSTNULLS LAST表示索引中空值的排列顺序,升序索引时默认为NULLS LAST,降序索引时默认为NULLS FIRST

如果我们经常使用 name 字段作为查询条件,可以为 test 表创建以下索引:

CREATE INDEX test_name_index ON test (name);

创建索引之后,优化器会自动选择是否使用索引,例如:

explain analyze
SELECT * FROM test WHERE name IS NULL;
QUERY PLAN                                                                                                           |
---------------------------------------------------------------------------------------------------------------------|
Index Scan using test_name_index on test  (cost=0.43..5.77 rows=1 width=15) (actual time=0.036..0.037 rows=0 loops=1)|Index Cond: (name IS NULL)                                                                                         |
Planning Time: 1.067 ms                                                                                              |
Execution Time: 0.048 ms                                                                                             |

基于索引字段的IS NULL运算符同样可以利用索引进行优化。

唯一索引

在创建索引时,可以使用UNIQUE关键字指定唯一索引:

CREATE UNIQUE INDEX index_name
ON table_name (column_name [ASC | DESC] [NULLS FIRST | NULLS LAST]);

唯一索引可以用于实现唯一约束,PostgreSQL 目前只支持 B-树类型的唯一索引。多个 NULL 值被看作是不同的值,因此唯一索引字段可以存在多个空值。

对于主键和唯一约束,PostgreSQL 会自动创建一个唯一索引,从而确保唯一性。

多列索引

PostgreSQL 支持基于多个字段的索引,也就是多列索引(复合索引)。默认情况下,一个多列索引最多可以使用 32 个字段。只有B-树、GIST、GIN 和 BRIN 索引支持多列索引。

CREATE [UNIQUE] INDEX index_name ON table_name
[USING method]
(column1 [ASC | DESC] [NULLS FIRST | NULLS LAST], ...);

对于多列索引,应该将最常作为查询条件使用的字段放在左边,较少使用的字段放在右边。例如,基于(c1, c2, c3)创建的索引可以优化以下查询:

WHERE c1 = v1 and c2 = v2 and c3 = v3;
WHERE c1 = v1 and c2 = v2;
WHERE c1 = v1;

但是以下查询无法使用该索引:

WHERE c2 = v2;
WHERE c3 = v3;
WHERE c2 = v2 and c3 = v3;

对于多列唯一索引,字段的组合值不能重复;但是如果某个字段是空值,其他字段可以出现重复值。

函数索引

函数索引,也叫表达式索引,是指基于某个函数或者表达式的值创建的索引。PostgreSQL 中创建函数索引的语法如下:

CREATE [UNIQUE] INDEX index_name 
ON table_name (expression);

expression 是基于字段的表达式或者函数。

以下查询在 name 字段上使用了 upper 函数:

explain analyze
SELECT * FROM test WHERE upper(name) ='VAL:10000';
QUERY PLAN                                                                                                                 |
---------------------------------------------------------------------------------------------------------------------------|
Gather  (cost=1000.00..122556.19 rows=50001 width=15) (actual time=18.629..7310.422 rows=1 loops=1)                        |Workers Planned: 2                                                                                                       |Workers Launched: 2                                                                                                      |->  Parallel Seq Scan on test  (cost=0.00..116556.09 rows=20834 width=15) (actual time=4746.266..7171.452 rows=0 loops=3)|Filter: (upper(name) = 'VAL:10000'::text)                                                                          |Rows Removed by Filter: 3333333                                                                                    |
Planning Time: 0.100 ms                                                                                                    |
Execution Time: 7310.444 ms                                                                                                |

虽然 name 字段上存在索引 test_name_index,但是函数会导致优化器无法使用该索引。为了优化这种不分区大小写的查询语句,可以基于 name 字段创建一个函数索引:

drop index test_name_index;
create index test_name_index on test(upper(name));

再次查看该语句的执行计划:

explain analyze
SELECT * FROM test WHERE upper(name) ='VAL:10000';
QUERY PLAN                                                                                                                     |
-------------------------------------------------------------------------------------------------------------------------------|
Bitmap Heap Scan on test  (cost=1159.93..57095.47 rows=50000 width=15) (actual time=17.046..17.047 rows=1 loops=1)             |Recheck Cond: (upper(name) = 'VAL:10000'::text)                                                                              |Heap Blocks: exact=1                                                                                                         |->  Bitmap Index Scan on test_name_index  (cost=0.00..1147.43 rows=50000 width=0) (actual time=17.032..17.032 rows=1 loops=1)|Index Cond: (upper(name) = 'VAL:10000'::text)                                                                          |
Planning Time: 1.985 ms                                                                                                        |
Execution Time: 17.080 ms                                                                                                      |

函数索引的维护成本比较高,因为插入和更新时都需要进行函数计算。

部分索引

部分索引(partial index)是只针对表中部分数据行创建的索引通过一个WHERE子句指定需要索引的行。例如,对于订单表 orders,绝大部的订单都处于完成状态;我们只需要针对未完成的订单进行查询跟踪,可以创建一个部分索引:

create table orders(order_id int primary key, order_ts timestamp, finished boolean);create index orders_unfinished_index
on orders (order_id)
where finished is not true;

该索引只包含了未完成的订单 id,比直接基于 finished 字段创建的索引小很多。它可以用于优化未完成订单的查询:

explain analyze
select order_id
from orders
where finished is not true;
QUERY PLAN                                                                                                                      |
--------------------------------------------------------------------------------------------------------------------------------|
Bitmap Heap Scan on orders  (cost=4.38..24.33 rows=995 width=4) (actual time=0.010..0.010 rows=0 loops=1)                       |Recheck Cond: (finished IS NOT TRUE)                                                                                          |->  Bitmap Index Scan on orders_unfinished_index  (cost=0.00..4.13 rows=995 width=0) (actual time=0.004..0.004 rows=0 loops=1)|
Planning Time: 0.130 ms                                                                                                         |
Execution Time: 0.049 ms                                                                                                        |

覆盖索引

PostgreSQL 中的索引都属于二级索引,意味着索引和数据是分开存储的。因此通过索引查找数据即需要访问索引,又需要访问表,而表的访问是随机 I/O。

为了解决这个性能问题,PostgreSQL 支持 Index-Only 扫描,只需要访问索引的数据就能获得需要的结果,而不需要再次访问表中的数据。例如:

CREATE TABLE t (a int, b int, c int);
CREATE UNIQUE INDEX idx_t_ab ON t USING btree (a, b) INCLUDE (c);

以上语句基于字段 a 和 b 创建了多列索引,同时利用INCLUDE在索引的叶子节点存储了字段 c 的值。以下查询可以利用 Index-Only 扫描:

explain analyze
select a, b, c 
from t 
where a = 100 and b = 200;
QUERY PLAN                                                                                                      |
----------------------------------------------------------------------------------------------------------------|
Index Only Scan using idx_t_ab on t  (cost=0.15..8.17 rows=1 width=12) (actual time=0.007..0.007 rows=0 loops=1)|Index Cond: ((a = 100) AND (b = 200))                                                                         |Heap Fetches: 0                                                                                               |
Planning Time: 0.078 ms                                                                                         |
Execution Time: 0.021 ms                                                                                        |

以上查询只返回索引字段(a、b)和覆盖的字段(c),可以仅通过扫描索引即可返回结果。

B-树索引支持 Index-Only 扫描,GiST 和 SP-GiST 索引支持某些运算符的 Index-Only 扫描,其他索引不支持这种方式。

查看索引

PostgreSQL 提供了一个关于索引的视图 pg_indexes,可以用于查看索引的信息:

select * from pg_indexes where tablename = 'test';
schemaname|tablename|indexname      |tablespace|indexdef                                                             |
----------|---------|---------------|----------|---------------------------------------------------------------------|
public    |test     |test_id_index  |          |CREATE INDEX test_id_index ON public.test USING btree (id)           |
public    |test     |test_name_index|          |CREATE INDEX test_name_index ON public.test USING btree (upper(name))|

该视图包含的字段依次为:模式名、表名、索引名、表空间以及索引的定义语句。

如果使用 psql 客户端连接,可以使用\d table_name命令查看表的结构,包括表中的索引信息。

维护索引

PostgreSQL 提供了一些修改和重建索引的方法:

ALTER INDEX index_name RENAME TO new_name;
ALTER INDEX index_name SET TABLESPACE tablespace_name;REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM }  index_name;

两个ALTER INDEX语句分别用于重命名索引和移动索引到其他表空间;REINDEX用于重建索引数据,支持不同级别的索引重建。

另外,索引被创建之后,系统会在修改数据的同时自动更新索引。不过,我们需要定期执行ANALYZE命令更新数据库的统计信息,以便优化器能够合理使用索引。

删除索引

如果需要删除一个已有的索引,可以使用以下命令:

DROP INDEX index_name [ CASCADE | RESTRICT ];

CASCADE 表示级联删除其他依赖该索引的对象;RESTRICT 表示如果存在依赖于该索引的对象,将会拒绝删除操作。默认为 RESTRICT。

我们可以使用以下语句删除 test 上的索引:

DROP INDEX test_id_index, test_name_index;

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

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

相关文章

基于ASP.NET MVC技术的图书管理系统的设计与实现

基于ASP.NET MVC技术的图书管理系统的设计与实现 摘要&#xff1a;图书管理系统是一套高新科学技术和图书知识信息以及传统历史文化完美结合的体现。它改变了传统图书收藏的静态书本式图书服务特征&#xff0c;实现了多媒体存取、远程网络传输、智能化检索、跨库无缝链接、创造…

type-c充电器输出电压5V9V12V15V20V PD协议诱骗快充应用方案

Type-C接口的PD充电器&#xff08;如iPhone的20W充电器&#xff09;默认是没有电压输出的&#xff0c;想要让Type-C的充电器输出5V、9V、12V、15V、20V&#xff0c;只需要在产品上使用一颗快充取电芯片XSP08即可。 工作原理&#xff1a; 各类小家电产品如平板电脑、智能穿戴产…

服务器感染了.mallox勒索病毒,如何确保数据文件完整恢复?

尊敬的读者&#xff1a; 随着数字化时代的不断发展&#xff0c;网络安全问题变得日益突出。近日&#xff0c;一种新的威胁——.mallox病毒&#xff0c;以其高度狡猾的勒索手段引起了广泛关注。本文将深入介绍.mallox病毒的威胁、如何应对被其感染的情况&#xff0c;以及如何通…

私有化外卖软件:打造专属美食配送体验

随着互联网的普及和人们生活节奏的加快&#xff0c;外卖已经成为人们日常生活的一部分。为了满足客户的个性化需求&#xff0c;我们开发了一款私有化外卖软件&#xff0c;旨在为您提供专属的美食配送服务。 一、定制化服务&#xff1a;满足您的独特需求 我们的私有化外卖软件可…

什么是Ros(二)- 结构和通讯概述

目录 1.架构 2.通讯 参考文献 上接&#xff1a;什么是Ros&#xff08;一&#xff09;-CSDN博客 1.架构 共三层&#xff1a;OS 层&#xff0c;中间层&#xff0c;应用层。 OS 层&#xff1a;OS 层是操作系统层也就是我们现在使用的ubuntu&#xff08;linux&#xff09;&…

win10下在Qt中使用VTK(安装VS2017+安装QT5.9.9+编译配置VTK8.2.0)

目录 前言一、安装Visual Studio20171&#xff09;官网下载可执行的安装程序2&#xff09;安装3&#xff09;启动 二、安装Qt 5.9.91&#xff09;下载可执行的安装程序2&#xff09;安装3&#xff09;配置环境变量 三、安装Cmake1&#xff09;下载可执行的安装程序2&#xff09…

【深度优先】LeetCode1932:合并多棵二叉搜索树

作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你 n 个 二叉搜索树的根节点 &#xff0c;存储在数组 trees 中&#xff08;下标从 0 开始&#xff09;&#xff0c;对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 &#xff0…

令人疑惑的Promise相关问题

令人疑惑的Promise相关问题 问题1 const promise new Promise((resolve, reject) > {reject(Error(Error occurred)); });promise.catch(error > console.log(error.message)); promise.catch(error > console.log(error.message));输出&#xff1a; Error occurr…

AWS中使用ECS时ecsTaskExecutionRole缺失

文章目录 问题解决参考 问题 在AWS中使用Amazon Elastic Container Service (Amazon ECS) 创建集群&#xff0c;任务&#xff0c;服务和容器时返回ecsTaskExecutionRole的问题&#xff0c;进行解决。 在事件中查看具体报错如下&#xff1a; service Windows-test failed to l…

一种excel多线程并发写sheet的方案

一、背景 有一次项目的需求要求导出excel&#xff0c;并且将不同的数据分别写到不同的sheet中。 二、 方案概述 首先一开始使用easyexcel去导出excel&#xff0c;结果发现导出时间需要3秒左右。于是想着能不能缩短excel导出时间&#xff0c;于是第一次尝试使用异步线程去查询数…

人工智能原理复习--确定性推理

文章目录 上一篇推理概述自然演绎推理合适公式 归结演绎推理归结原理归结反演 提升归结效率下一篇 上一篇 人工智能原理复习–知识表示&#xff08;二&#xff09; 推理概述 推理就是按某种策略由已知判断推出另一判断的思维过程 分类&#xff1a; 演绎推理、归纳推理、默…

什么是GRS认证?什么让它这么火?

【什么是GRS认证&#xff1f;什么让它这么火&#xff1f;】 对于外贸公司而言&#xff0c;GRS&#xff08;Global Recycled Standard&#xff09;认证成为了一个备受关注的认证标准&#xff0c;它对于现代企业来说具有重要的意义。GRS认证是针对纺织品行业的认证标准&#xff0…

kafka 集群 ZooKeeper 模式搭建

Apache Kafka是一个开源分布式事件流平台&#xff0c;被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用程序 Kafka 官网&#xff1a;Apache Kafka 关于ZooKeeper的弃用 根据 Kafka官网信息&#xff0c;随着Apache Kafka 3.5版本的发布&#xff0c;Zookeeper现…

Christmas is Coming,一起来DIY雪花灯啦

亲爱的朋友们&#xff0c;圣诞节即将到来&#xff01;是不是很期待和家人、朋友一起欢度圣诞夜呢&#xff1f;KCC深圳联合立创开源特别为大家精心挑选了一款氛围感满满的雪花灯&#xff0c;让我们一起创造自己的圣诞礼物~ 彩色丝印PCB版的触摸无极调光雪花灯 哇&#xff0c;立创…

VL53-400激光测距传感器

一、产品简介 先由激光二极管对准目标发射激光脉冲。经目标反射后激光向各方向散射。部分散射光返回到传感器接收器&#xff0c;被光学系统接收后成像到雪崩光电二极管上。雪崩光电二极管是一种内部具有放大功能的光学传感器&#xff0c;因此它能检测极其微弱的光信号。记录并…

6.9 Windows驱动开发:内核枚举进线程ObCall回调

在笔者上一篇文章《内核枚举Registry注册表回调》中我们通过特征码定位实现了对注册表回调的枚举&#xff0c;本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回调以及ThreadObCall线程回调&#xff0c;之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用…

XML处理相关——学习一些处理脚本(1)——(待完善)

python脚本 import osfrom Bio.Blast import NCBIXMLimport FetchUtil #https://github.com/NiallScott/FetchUtils import randomif not os.path.exists(XML):os.mkdir(XML) if not os.path.exists(dicts):os.mkdir(dicts)def bestrecipblast(org, seed, thresh5, queueNone)…

02.PostgreSQL 查询处理期间发生了什么?

PostgreSQL 查询处理期间发生了什么&#xff1f; 文中主要内容引用自PostgreSQL指南&#xff1a;内幕探索 查询处理是PostgreSQL中最为复杂的子系统。如PostgreSQL官方文档所述&#xff0c;PostgreSQL支持SQL2011标准中的大多数特性&#xff0c;查询处理子系统能够高效地处理这…

数据库相关算法题 V1

超过经理收入的员工 超过经理收入的员工显然是要将同一张表&#xff0c;作为经理和员工表连接。这里存在两种方法&#xff0c;一种是采用WHERE SELECTa.Name AS Employee FROMEmployee AS a,Employee AS b WHEREa.ManagerId b.IdAND a.Salary > b.Salary另一种是使用JOIN…

【BUG】SpringBoot项目Long类型数据返回前端精度丢失问题

问题描述 后端再给前端返回数据&#xff0c;使用Long类型的时候存在精度丢失问题。 原因分析&#xff1a; 分布式项目中广泛使用雪花算法生成ID作为数据库表的主键&#xff0c;Long类型的雪花ID有19位&#xff0c;而前端接收Long类型用的是number类型&#xff0c;但是number…