PostgreSQL 分区表——范围分区SQL实践
PostgreSQL 分区表——范围分区SQL实践
- 1、环境准备
- 1-1、新增原始表
- 1-2、执行脚本新增2400w行
- 1-3、创建pg分区表-分区键为创建时间
- 1-4、创建24年所有分区
- 1-5、设置默认分区(兜底用)
- 1-6、迁移数据
- 1-7、创建分区表索引
- 2、SQL增删改查测试
- 2-1、查询速度对比
- 2-1-1、查询总数量时间对比
- 查询总数量反直觉分析
- 2-2-1、带上分区键查询对比
- 带上分区键在分表区间内查询
- 带上分区键跨分表区间查询
- 2-2、删除速度对比
- 2-2-1、全量删除TRUNCATE
- 2-2-2、删除某个月数据
- 原始表DELETE 145.372s
- 分区表DELETE(未指定分区)225.896s
- 分区表DELETE(指定分区)242.770s
- 分区表TRUNCATE(指定分区)13.156s
- 2-2-3、删除一条数据
- 原始表 平均8.009s
- 分区表(未带上分区键) 平均7.858s
- 分区表(带上分区键) 平均1.567s
- 2-3、写入速度对比
- 2-2-1、全量插入2400w数据,均匀分布在每个月
- 原始表 3387.520s
- 分区表 4988.111s
- 2-2-2、指定某个月插入10w数据
- 原始表 63.572s
- 分区表(未指定分区) 58.759s
- 分区表(指定分区) 48.098s
- 2-4、更新速度对比
- 2-4-1、修改指定月份的处理人信息
- 原始表 538.133s
- 分区表(未指定分区) 1252.286s
- 分区表(指定分区) 1252.286s
- 2-4-1、根据主键修处理人信息
- 原始表 12.597s
- 分区表(未带上分区键) 10.870s
- 分区表(带上分区键) 0.438s
- 3、总结
1、环境准备
1-1、新增原始表
CREATE TABLE t_common_work_order_log (work_order_log_id varchar(32) COLLATE pg_catalog.default NOT NULL,operation_type int2,work_order_id varchar(32) COLLATE pg_catalog.default,work_order_name varchar(100) COLLATE pg_catalog.default,work_order_type int4,biz_location_id int4,planned_completion_time timestamp(6),actual_completion_time timestamp(6),handle_user_account varchar(100) COLLATE pg_catalog.default,handle_user_name varchar(100) COLLATE pg_catalog.default,create_time timestamp(0),create_by_uuid varchar(32) COLLATE pg_catalog.default,create_by_account varchar(32) COLLATE pg_catalog.default,create_by_name varchar(100) COLLATE pg_catalog.default,last_update_time timestamp(0),last_update_uuid varchar(32) COLLATE pg_catalog.default,last_update_account varchar(32) COLLATE pg_catalog.default,last_update_name varchar(100) COLLATE pg_catalog.default,biz_attribute_1 varchar(255) COLLATE pg_catalog.default,biz_attribute_2 varchar(255) COLLATE pg_catalog.default,biz_attribute_3 varchar(255) COLLATE pg_catalog.default,biz_attribute_4 varchar(255) COLLATE pg_catalog.default,biz_attribute_5 varchar(255) COLLATE pg_catalog.default,biz_attribute_6 varchar(255) COLLATE pg_catalog.default,biz_attribute_7 varchar(255) COLLATE pg_catalog.default,biz_attribute_8 varchar(255) COLLATE pg_catalog.default,biz_attribute_9 varchar(255) COLLATE pg_catalog.default,biz_attribute_10 varchar(255) COLLATE pg_catalog.default,biz_attribute_11 varchar(255) COLLATE pg_catalog.default,biz_attribute_12 varchar(255) COLLATE pg_catalog.default,biz_attribute_13 varchar(255) COLLATE pg_catalog.default,biz_attribute_14 varchar(255) COLLATE pg_catalog.default,biz_attribute_15 varchar(255) COLLATE pg_catalog.default,biz_attribute_16 varchar(255) COLLATE pg_catalog.default,biz_attribute_17 varchar(255) COLLATE pg_catalog.default,biz_attribute_18 varchar(255) COLLATE pg_catalog.default,biz_attribute_19 varchar(255) COLLATE pg_catalog.default,biz_attribute_20 varchar(255) COLLATE pg_catalog.default
)
;ALTER TABLE t_common_work_order_log OWNER TO postgres;CREATE INDEX order_log_biz_location_id_index ON t_common_work_order_log USING btree (biz_location_id pg_catalog.int4_ops ASC NULLS LAST
);CREATE INDEX order_log_create_by_account_index ON t_common_work_order_log USING btree (create_by_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_create_time_index ON t_common_work_order_log USING btree (create_time pg_catalog.timestamp_ops ASC NULLS LAST
);CREATE INDEX order_log_handle_user_account_index ON t_common_work_order_log USING btree (handle_user_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_last_update_account_index ON t_common_work_order_log USING btree (last_update_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_last_update_time_index ON t_common_work_order_log USING btree (last_update_time pg_catalog.timestamp_ops ASC NULLS LAST
);CREATE INDEX order_log_operation_type_index ON t_common_work_order_log USING btree (operation_type pg_catalog.int2_ops ASC NULLS LAST
);CREATE INDEX order_log_work_order_name_index ON t_common_work_order_log USING btree (work_order_name COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_work_order_type_index ON t_common_work_order_log USING btree (work_order_type pg_catalog.int4_ops ASC NULLS LAST
);COMMENT ON COLUMN t_common_work_order_log.work_order_log_id IS '工单日志ID';COMMENT ON COLUMN t_common_work_order_log.operation_type IS '操作类型';COMMENT ON COLUMN t_common_work_order_log.work_order_id IS '工单ID';COMMENT ON COLUMN t_common_work_order_log.work_order_name IS '工单名称';COMMENT ON COLUMN t_common_work_order_log.work_order_type IS '工单类型';COMMENT ON COLUMN t_common_work_order_log.biz_location_id IS '业务位置ID';COMMENT ON COLUMN t_common_work_order_log.planned_completion_time IS '计划完成时间';COMMENT ON COLUMN t_common_work_order_log.actual_completion_time IS '实际完成时间';COMMENT ON COLUMN t_common_work_order_log.handle_user_account IS '处理人账号';COMMENT ON COLUMN t_common_work_order_log.handle_user_name IS '处理人名称';COMMENT ON COLUMN t_common_work_order_log.create_time IS '创建时间';COMMENT ON COLUMN t_common_work_order_log.create_by_uuid IS '创建人uuid';COMMENT ON COLUMN t_common_work_order_log.create_by_account IS '创建人账号';COMMENT ON COLUMN t_common_work_order_log.create_by_name IS '创建人名称';COMMENT ON COLUMN t_common_work_order_log.last_update_time IS '最后更新时间';COMMENT ON COLUMN t_common_work_order_log.last_update_uuid IS '最后跟新人uuid';COMMENT ON COLUMN t_common_work_order_log.last_update_account IS '最后更新人账号';COMMENT ON COLUMN t_common_work_order_log.last_update_name IS '最后更新人名称';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_1 IS '业务属性1';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_2 IS '业务属性2';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_3 IS '业务属性3';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_4 IS '业务属性4';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_5 IS '业务属性5';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_6 IS '业务属性6';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_7 IS '业务属性7';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_8 IS '业务属性8';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_9 IS '业务属性9';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_10 IS '业务属性10';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_11 IS '业务属性11';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_12 IS '业务属性12';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_13 IS '业务属性13';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_14 IS '业务属性14';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_15 IS '业务属性15';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_16 IS '业务属性16';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_17 IS '业务属性17';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_18 IS '业务属性18';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_19 IS '业务属性19';COMMENT ON COLUMN t_common_work_order_log.biz_attribute_20 IS '业务属性20';COMMENT ON TABLE t_common_work_order_log IS '某工单操作日志表';COMMENT ON INDEX order_log_biz_location_id_index IS '位置索引';COMMENT ON INDEX order_log_create_by_account_index IS '创建人索引';COMMENT ON INDEX order_log_create_time_index IS '创建时间索引';COMMENT ON INDEX order_log_handle_user_account_index IS '处理人索引';COMMENT ON INDEX order_log_last_update_account_index IS '最后更新人索引';COMMENT ON INDEX order_log_last_update_time_index IS '最后更新时间索引';COMMENT ON INDEX order_log_operation_type_index IS '操作类型索引';COMMENT ON INDEX order_log_work_order_name_index IS '工单名称索引';COMMENT ON INDEX order_log_work_order_type_index IS '工单类型索引';
1-2、执行脚本新增2400w行
-- 1. 首先创建随机中文名函数
CREATE OR REPLACE FUNCTION random_chinese_name() RETURNS varchar(100) AS $$
DECLAREsurnames varchar[] := ARRAY['张','王','李','赵','刘','陈','杨','黄','吴','周','徐','孙','马','朱','胡','林','郭','何','高','罗'];givennames varchar[] := ARRAY['伟','芳','娜','秀英','敏','静','丽','强','磊','军','洋','勇','艳','杰','娟','涛','明','超','秀兰','霞'];
BEGINRETURN surnames[floor(random()*array_length(surnames,1)+1)] || givennames[floor(random()*array_length(givennames,1)+1)];
END;
$$ LANGUAGE plpgsql;-- 2. 执行数据生成DO块
DO $$
DECLAREmonth_start timestamp;month_end timestamp;month_intervals interval[] := ARRAY[interval '0 months', interval '1 month', interval '2 months',interval '3 months', interval '4 months', interval '5 months',interval '6 months', interval '7 months', interval '8 months',interval '9 months', interval '10 months', interval '11 months'];month_interval interval;
BEGIN-- 设置维护内存提高性能SET LOCAL maintenance_work_mem = '1GB';SET LOCAL work_mem = '256MB';-- 为每个月生成200万条数据FOREACH month_interval IN ARRAY month_intervals LOOPmonth_start := (date '2024-01-01' + month_interval)::timestamp;month_end := (date '2024-01-01' + month_interval + interval '1 month')::timestamp;RAISE NOTICE 'Generating data for month: % (%)', to_char(month_start, 'YYYY-MM'), to_char(clock_timestamp(), 'YYYY-MM-DD HH24:MI:SS');-- 每月插入200万条INSERT INTO t_common_work_order_log (work_order_log_id,operation_type,work_order_id,work_order_name,work_order_type,biz_location_id,planned_completion_time,actual_completion_time,handle_user_account,handle_user_name,create_time,create_by_uuid,create_by_account,create_by_name,last_update_time,last_update_uuid,last_update_account,last_update_name,biz_attribute_1,biz_attribute_2,biz_attribute_3,biz_attribute_4,biz_attribute_5,biz_attribute_6,biz_attribute_7,biz_attribute_8,biz_attribute_9,biz_attribute_10,biz_attribute_11,biz_attribute_12,biz_attribute_13,biz_attribute_14,biz_attribute_15,biz_attribute_16,biz_attribute_17,biz_attribute_18,biz_attribute_19,biz_attribute_20)SELECT substr(md5(random()::text || i::text), 1, 32),floor(random() * 5 + 1)::int2,'WO' || (2000000*extract(month FROM month_start) + i)::varchar,(ARRAY['设备维修','软件升级','网络故障','数据迁移','常规维护'])[floor(random()*5+1)],floor(random() * 10 + 1)::int4,floor(random() * 100 + 1)::int4,month_start + random() * (month_end - month_start) + (interval '1 day' * floor(random() * 3 + 1)),CASE WHEN random() > 0.2 THEN month_start + random() * (month_end - month_start) + (interval '1 hour' * floor(random() * 4 - 2))ELSE NULL END,'user' || floor(random() * 100 + 1)::varchar,random_chinese_name(),month_start + random() * (month_end - month_start),substr(md5(random()::text || i::text), 1, 32),'admin' || floor(random() * 10 + 1)::varchar,'系统管理员' || floor(random() * 5 + 1)::varchar,month_start + random() * (month_end - month_start) + (interval '1 hour' * floor(random() * 24)),substr(md5(random()::text || i::text), 1, 32),'user' || floor(random() * 100 + 1)::varchar,random_chinese_name(),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text)FROM generate_series(1, 2000000) AS i;RAISE NOTICE 'Completed month: %, % records inserted', to_char(month_start, 'YYYY-MM'), 2000000;END LOOP;
END $$;
1-3、创建pg分区表-分区键为创建时间
-- 1-创建分区表
CREATE TABLE t_common_work_order_log_new (work_order_log_id varchar(32) NOT NULL,operation_type int2,work_order_id varchar(32),work_order_name varchar(100),work_order_type int4,biz_location_id int4,planned_completion_time timestamp,actual_completion_time timestamp,handle_user_account varchar(100),handle_user_name varchar(100),create_time timestamp(0),create_by_uuid varchar(32),create_by_account varchar(32),create_by_name varchar(100),last_update_time timestamp(0),last_update_uuid varchar(32),last_update_account varchar(32),last_update_name varchar(100),biz_attribute_1 varchar(255),biz_attribute_2 varchar(255),biz_attribute_3 varchar(255),biz_attribute_4 varchar(255),biz_attribute_5 varchar(255),biz_attribute_6 varchar(255),biz_attribute_7 varchar(255),biz_attribute_8 varchar(255),biz_attribute_9 varchar(255),biz_attribute_10 varchar(255),biz_attribute_11 varchar(255),biz_attribute_12 varchar(255),biz_attribute_13 varchar(255),biz_attribute_14 varchar(255),biz_attribute_15 varchar(255),biz_attribute_16 varchar(255),biz_attribute_17 varchar(255),biz_attribute_18 varchar(255),biz_attribute_19 varchar(255),biz_attribute_20 varchar(255)
) PARTITION BY RANGE (create_time)
;
1-4、创建24年所有分区
-- 2-创建所24年有分区
CREATE TABLE t_common_work_order_log_202401 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE t_common_work_order_log_202402 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
CREATE TABLE t_common_work_order_log_202403 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-03-01') TO ('2024-04-01');
CREATE TABLE t_common_work_order_log_202404 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-04-01') TO ('2024-05-01');
CREATE TABLE t_common_work_order_log_202405 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-05-01') TO ('2024-06-01');
CREATE TABLE t_common_work_order_log_202406 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-06-01') TO ('2024-07-01');
CREATE TABLE t_common_work_order_log_202407 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-07-01') TO ('2024-08-01');
CREATE TABLE t_common_work_order_log_202408 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-08-01') TO ('2024-09-01');
CREATE TABLE t_common_work_order_log_202409 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-09-01') TO ('2024-10-01');
CREATE TABLE t_common_work_order_log_202410 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-10-01') TO ('2024-11-01');
CREATE TABLE t_common_work_order_log_202411 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-11-01') TO ('2024-12-01');
CREATE TABLE t_common_work_order_log_202412 PARTITION OF t_common_work_order_log_new
FOR VALUES FROM ('2024-12-01') TO ('2025-01-01');
1-5、设置默认分区(兜底用)
当写入数据的创建时间没有匹配到已有分区时,会写入默认分区,避免数据库异常
-- 3. 设置默认分区(兜底用)
CREATE TABLE t_common_work_order_log_default PARTITION OF t_common_work_order_log_new DEFAULT;
1-6、迁移数据
-- 4. 迁移数据
INSERT INTO t_common_work_order_log_new
SELECT * FROM t_common_work_order_log;
1-7、创建分区表索引
-- 5. 创建分区表索引
CREATE INDEX order_log_biz_location_id_p_index ON t_common_work_order_log_new USING btree (biz_location_id pg_catalog.int4_ops ASC NULLS LAST
);CREATE INDEX order_log_create_by_account_p_index ON t_common_work_order_log_new USING btree (create_by_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_create_time_p_index ON t_common_work_order_log_new USING btree (create_time pg_catalog.timestamp_ops ASC NULLS LAST
);CREATE INDEX order_log_handle_user_account_p_index ON t_common_work_order_log_new USING btree (handle_user_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_last_update_account_p_index ON t_common_work_order_log_new USING btree (last_update_account COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_last_update_time_p_index ON t_common_work_order_log_new USING btree (last_update_time pg_catalog.timestamp_ops ASC NULLS LAST
);CREATE INDEX order_log_operation_type_p_index ON t_common_work_order_log_new USING btree (operation_type pg_catalog.int2_ops ASC NULLS LAST
);CREATE INDEX order_log_work_order_name_p_index ON t_common_work_order_log_new USING btree (work_order_name COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);CREATE INDEX order_log_work_order_type_p_index ON t_common_work_order_log_new USING btree (work_order_type pg_catalog.int4_ops ASC NULLS LAST
);
2、SQL增删改查测试
2-1、查询速度对比
2-1-1、查询总数量时间对比
- 非分区表首次查询约为
800s
,预热后查询为2.4s
- 分区表首次查询约为
380s
,预热后查询为1.26s
-- 819.769s/2.427s
SELECT COUNT(*) FROM t_common_work_order_log;
-- 387.680s/1.260s
SELECT COUNT(*) FROM t_common_work_order_log_new;
查询总数量反直觉分析
为什么查询总数量分区表会比非分区表快?
执行EXPLAIN ANALYZE可以发现,分区表为并行扫描,最后会将并行扫描结果汇总:
-- 819.769s/2.427s
EXPLAIN ANALYZE SELECT COUNT(*) FROM t_common_work_order_log;
-- 387.680s/1.260s
EXPLAIN ANALYZE SELECT COUNT(*) FROM t_common_work_order_log_new;
Finalize Aggregate (cost=4126001.24..4126001.25 rows=1 width=8) (actual time=2554.156..2559.141 rows=1 loops=1)-> Gather (cost=4126001.03..4126001.24 rows=2 width=8) (actual time=2554.069..2559.129 rows=3 loops=1)Workers Planned: 2Workers Launched: 2-> Partial Aggregate (cost=4125001.03..4125001.04 rows=1 width=8) (actual time=2540.244..2540.245 rows=1 loops=3)-> Parallel Seq Scan on t_common_work_order_log (cost=0.00..4100001.02 rows=10000002 width=0) (actual time=0.036..2256.003 rows=8000000 loops=3)
Planning Time: 0.155 ms
JIT:Functions: 8Options: Inlining true, Optimization true, Expressions true, Deforming trueTiming: Generation 0.595 ms, Inlining 66.620 ms, Optimization 16.470 ms, Emission 12.494 ms, Total 96.179 ms
Execution Time: 2559.602 ms
Finalize Aggregate (cost=2071847.96..2071847.97 rows=1 width=8) (actual time=1737.444..1748.516 rows=1 loops=1)-> Gather (cost=2071847.74..2071847.95 rows=2 width=8) (actual time=1737.313..1748.503 rows=3 loops=1)Workers Planned: 2Workers Launched: 2-> Partial Aggregate (cost=2070847.74..2070847.75 rows=1 width=8) (actual time=1725.717..1725.721 rows=1 loops=3)-> Parallel Append (cost=0.43..2045847.74 rows=10000000 width=0) (actual time=35.470..1495.583 rows=8000000 loops=3)-> Parallel Index Only Scan using t_common_work_order_log_202406_operation_type_idx on t_common_work_order_log_202406 t_common_work_order_log_new_6 (cost=0.43..274942.74 rows=833486 width=0) (actual time=42.229..175.568 rows=2000366 loops=1)Heap Fetches: 94752-> Parallel Index Only Scan using t_common_work_order_log_202407_operation_type_idx on t_common_work_order_log_202407 t_common_work_order_log_new_7 (cost=0.43..203921.26 rows=833669 width=0) (actual time=42.227..164.912 rows=2000805 loops=1)Heap Fetches: 67128-> Parallel Index Only Scan using t_common_work_order_log_202410_work_order_type_idx on t_common_work_order_log_202410 t_common_work_order_log_new_10 (cost=0.43..25125.31 rows=833677 width=0) (actual time=0.073..101.861 rows=2000824 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_202404_work_order_type_idx on t_common_work_order_log_202404 t_common_work_order_log_new_4 (cost=0.43..25116.53 rows=833459 width=0) (actual time=0.055..101.724 rows=2000302 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_202403_work_order_type_idx on t_common_work_order_log_202403 t_common_work_order_log_new_3 (cost=0.43..25115.34 rows=833405 width=0) (actual time=0.075..101.928 rows=2000172 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_202402_work_order_type_idx on t_common_work_order_log_202402 t_common_work_order_log_new_2 (cost=0.43..25115.08 rows=833393 width=0) (actual time=0.049..101.426 rows=2000144 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_202401_work_order_type_idx on t_common_work_order_log_202401 t_common_work_order_log_new_1 (cost=0.43..25114.91 rows=833385 width=0) (actual time=0.079..101.461 rows=2000125 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_202412_work_order_type_idx on t_common_work_order_log_202412 t_common_work_order_log_new_12 (cost=0.43..22083.01 rows=732663 width=0) (actual time=0.044..89.077 rows=1758391 loops=1)Heap Fetches: 0-> Parallel Index Only Scan using t_common_work_order_log_default_work_order_type_idx on t_common_work_order_log_default t_common_work_order_log_new_13 (cost=0.29..3030.63 rows=100470 width=0) (actual time=0.050..12.340 rows=241127 loops=1)Heap Fetches: 0-> Parallel Seq Scan on t_common_work_order_log_202409 t_common_work_order_log_new_9 (cost=0.00..341619.16 rows=833216 width=0) (actual time=0.053..196.980 rows=666573 loops=3)-> Parallel Seq Scan on t_common_work_order_log_202411 t_common_work_order_log_new_11 (cost=0.00..341578.15 rows=833115 width=0) (actual time=0.048..296.090 rows=999738 loops=2)-> Parallel Seq Scan on t_common_work_order_log_202408 t_common_work_order_log_new_8 (cost=0.00..341574.07 rows=833107 width=0) (actual time=0.057..584.129 rows=1999457 loops=1)-> Parallel Seq Scan on t_common_work_order_log_202405 t_common_work_order_log_new_5 (cost=0.00..341511.55 rows=832955 width=0) (actual time=21.951..597.384 rows=1999092 loops=1)
Planning Time: 0.608 ms
JIT:Functions: 47Options: Inlining true, Optimization true, Expressions true, Deforming trueTiming: Generation 1.001 ms, Inlining 65.639 ms, Optimization 19.031 ms, Emission 21.833 ms, Total 107.504 ms
Execution Time: 1749.153 ms
2-2-1、带上分区键查询对比
带上分区键在分表区间内查询
查询2024年4月份总数据量
-- 原始表2.066s
SELECT COUNT(*) FROM t_common_work_order_log WHERE create_time > '2024-04-01' AND create_time < '2024-05-01';
-- 分区表0.715s
SELECT COUNT(*) FROM t_common_work_order_log_new WHERE create_time > '2024-04-01' AND create_time < '2024-05-01';
带上分区键跨分表区间查询
查询2024年5月~6月总数据量
-- 原始表3.303s
SELECT COUNT(*) FROM t_common_work_order_log WHERE create_time > '2024-05-01' AND create_time < '2024-07-01';
-- 分区表1.083s
SELECT COUNT(*) FROM t_common_work_order_log_new WHERE create_time > '2024-05-01' AND create_time < '2024-07-01';
2-2、删除速度对比
2-2-1、全量删除TRUNCATE
相同的数据量分区表删除耗时远远大于原始表
-- 清空速度对比:
TRUNCATE TABLE t_common_work_order_log;
TRUNCATE TABLE t_common_work_order_log_new;
2-2-2、删除某个月数据
原始表DELETE 145.372s
DELETE FROM t_common_work_order_log
WHERE create_time >= '2024-05-01 00:00:00' AND create_time < '2024-06-01 00:00:00';
分区表DELETE(未指定分区)225.896s
分区表DELETE(指定分区)242.770s
分区表TRUNCATE(指定分区)13.156s
2-2-3、删除一条数据
测试10次,每次删除一条
原始表 平均8.009s
-- 113.489s 10.768s 7.393s 6.713s 8.896s 6.089s 7.506s 8.005s 7.955s 6.838s
DELETE FROM t_common_work_order_log WHERE work_order_log_id = '0e817fcd240bf4ecbaf0b5d05e793b9f';
分区表(未带上分区键) 平均7.858s
-- 33.275s 7.227s 7.545s 8.674s 6.186s 10.045s 7.103s 5.707s 7.112s 8.972s
DELETE FROM t_common_work_order_log_new WHERE work_order_log_id = '8326be2f926c1437a8b623b044518888';
分区表(带上分区键) 平均1.567s
-- 0.346s 2.341s 1.003s 2.226s 0.620s 2.955s 1.191s 0.071s 7.196s 1.855s
DELETE
FROMt_common_work_order_log_new
WHEREcreate_time = '2024-3-27 23:58:50' AND work_order_log_id = '040ba71c39f80e1217296f262e8e999f';
2-3、写入速度对比
2-2-1、全量插入2400w数据,均匀分布在每个月
插入sql可以参考执行脚本新增2400w行
原始表 3387.520s
分区表 4988.111s
2-2-2、指定某个月插入10w数据
原始表 63.572s
-- 生成10万条6月数据
INSERT INTO t_common_work_order_log (work_order_log_id,operation_type,work_order_id,work_order_name,work_order_type,biz_location_id,planned_completion_time,actual_completion_time,handle_user_account,handle_user_name,create_time,create_by_uuid,create_by_account,create_by_name,last_update_time,last_update_uuid,last_update_account,last_update_name,biz_attribute_1,biz_attribute_2,biz_attribute_3,biz_attribute_4,biz_attribute_5,biz_attribute_6,biz_attribute_7,biz_attribute_8,biz_attribute_9,biz_attribute_10
)
SELECT -- work_order_log_id: UUID简写substr(md5(random()::text || i::text), 1, 32),-- operation_type: 1-5随机值floor(random() * 5 + 1)::int2,-- work_order_id: WO+6月标识+序号'WO202406' || lpad(i::text, 5, '0'),-- work_order_name: 随机工单类型(ARRAY['设备维修','软件升级','网络故障','数据迁移','常规维护'])[floor(random()*5+1)],-- work_order_type: 1-10随机值floor(random() * 10 + 1)::int4,-- biz_location_id: 1-100随机floor(random() * 100 + 1)::int4,-- planned_completion_time: 6月随机时间+1-3天(timestamp '2024-06-01' + random() * interval '30 days') + (interval '1 day' * floor(random() * 3 + 1)),-- actual_completion_time: 80%有值,在计划时间±2小时CASE WHEN random() > 0.2 THEN (timestamp '2024-06-01' + random() * interval '30 days') + (interval '1 hour' * floor(random() * 4 - 2))ELSE NULL END,-- handle_user_account: user+随机编号'user' || floor(random() * 50 + 1)::varchar,-- handle_user_name: 随机中文名random_chinese_name(),-- create_time: 6月随机时间timestamp '2024-06-01' + random() * interval '30 days',-- create_by_uuid: 随机UUID简写substr(md5(random()::text || i::text), 1, 32),-- create_by_account: admin+随机编号'admin' || floor(random() * 5 + 1)::varchar,-- create_by_name: 管理员+编号'系统管理员' || floor(random() * 3 + 1)::varchar,-- last_update_time: create_time+0-24小时timestamp '2024-06-01' + random() * interval '30 days' + (interval '1 hour' * floor(random() * 24)),-- last_update_uuid: 随机UUID简写substr(md5(random()::text || i::text), 1, 32),-- last_update_account: user+随机编号'user' || floor(random() * 50 + 1)::varchar,-- last_update_name: 随机中文名random_chinese_name(),-- biz_attribute_1-10: 随机MD5值md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text)
FROM generate_series(1, 100000) AS i;
分区表(未指定分区) 58.759s
-- 生成10万条6月数据
INSERT INTO t_common_work_order_log_new (work_order_log_id,operation_type,work_order_id,work_order_name,work_order_type,biz_location_id,planned_completion_time,actual_completion_time,handle_user_account,handle_user_name,create_time,create_by_uuid,create_by_account,create_by_name,last_update_time,last_update_uuid,last_update_account,last_update_name,biz_attribute_1,biz_attribute_2,biz_attribute_3,biz_attribute_4,biz_attribute_5,biz_attribute_6,biz_attribute_7,biz_attribute_8,biz_attribute_9,biz_attribute_10
)
SELECT -- work_order_log_id: UUID简写substr(md5(random()::text || i::text), 1, 32),-- operation_type: 1-5随机值floor(random() * 5 + 1)::int2,-- work_order_id: WO+6月标识+序号'WO202406' || lpad(i::text, 5, '0'),-- work_order_name: 随机工单类型(ARRAY['设备维修','软件升级','网络故障','数据迁移','常规维护'])[floor(random()*5+1)],-- work_order_type: 1-10随机值floor(random() * 10 + 1)::int4,-- biz_location_id: 1-100随机floor(random() * 100 + 1)::int4,-- planned_completion_time: 6月随机时间+1-3天(timestamp '2024-06-01' + random() * interval '30 days') + (interval '1 day' * floor(random() * 3 + 1)),-- actual_completion_time: 80%有值,在计划时间±2小时CASE WHEN random() > 0.2 THEN (timestamp '2024-06-01' + random() * interval '30 days') + (interval '1 hour' * floor(random() * 4 - 2))ELSE NULL END,-- handle_user_account: user+随机编号'user' || floor(random() * 50 + 1)::varchar,-- handle_user_name: 随机中文名random_chinese_name(),-- create_time: 6月随机时间timestamp '2024-06-01' + random() * interval '30 days',-- create_by_uuid: 随机UUID简写substr(md5(random()::text || i::text), 1, 32),-- create_by_account: admin+随机编号'admin' || floor(random() * 5 + 1)::varchar,-- create_by_name: 管理员+编号'系统管理员' || floor(random() * 3 + 1)::varchar,-- last_update_time: create_time+0-24小时timestamp '2024-06-01' + random() * interval '30 days' + (interval '1 hour' * floor(random() * 24)),-- last_update_uuid: 随机UUID简写substr(md5(random()::text || i::text), 1, 32),-- last_update_account: user+随机编号'user' || floor(random() * 50 + 1)::varchar,-- last_update_name: 随机中文名random_chinese_name(),-- biz_attribute_1-10: 随机MD5值md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text), md5(random()::text), md5(random()::text),md5(random()::text)
FROM generate_series(1, 100000) AS i;
分区表(指定分区) 48.098s
2-4、更新速度对比
2-4-1、修改指定月份的处理人信息
原始表 538.133s
UPDATE t_common_work_order_log
SET handle_user_account = 'hander-system'
WHEREcreate_time > '2024-07-01' AND create_time < '2024-08-01';
分区表(未指定分区) 1252.286s
UPDATE t_common_work_order_log_new
SET handle_user_account = 'hander-system'
WHEREcreate_time > '2024-07-01' AND create_time < '2024-08-01';
分区表(指定分区) 1252.286s
UPDATE t_common_work_order_log_new
SET handle_user_account = 'hander-system'
WHEREcreate_time > '2024-07-01' AND create_time < '2024-08-01';
2-4-1、根据主键修处理人信息
原始表 12.597s
UPDATE t_common_work_order_log
SET handle_user_account = 'hander-system-byid'
WHERE work_order_log_id = 'db3114ba4a676937269e2cf0ef7454b8';
分区表(未带上分区键) 10.870s
UPDATE t_common_work_order_log_new
SET handle_user_account = 'hander-system-byid'
WHERE work_order_log_id = '9ac76e7e262cd7b374d6939a7e0f4144';
分区表(带上分区键) 0.438s
UPDATE t_common_work_order_log_new
SET handle_user_account = 'hander-system-by shard id'
WHEREcreate_time = '2024-12-31 23:59:19' AND work_order_log_id = '9ac76e7e262cd7b374d6939a7e0f4144';
3、总结
文本基于PostgreSQL原生分区能力,以创建时间作为分区键进行水平分表验证,要想发挥分区表的优势,多需要带上分区键
进行操作,例如上文的删除以及更新操作中,带上分区键比未带分区键操作,性能存在10倍左右差异,但是进行大批量
的操作,分区表的优势不明显
,甚至有些场景还会非常慢。
PostgreSQL分区为数据库引擎内置功能,无需额外的应用层中间件,性能损失较小,提供了基础的分区能力,适用于如下场景:
- 数据量在单机可承受范围内(<5TB)
- 只需要表级别的分区
- 希望最小化技术栈复杂度
- 需要利用PG特定功能(如GIS、JSONB)
相关文章:
PostgreSQL 分区表——范围分区SQL实践
PostgreSQL 分区表——范围分区SQL实践 1、环境准备1-1、新增原始表1-2、执行脚本新增2400w行1-3、创建pg分区表-分区键为创建时间1-4、创建24年所有分区1-5、设置默认分区(兜底用)1-6、迁移数据1-7、创建分区表索引 2、SQL增删改查测试2-1、查询速度对比…...
第八节:进阶特性高频题-Pinia与Vuex对比
优势:无嵌套模块、Composition API友好、TypeScript原生支持 核心概念:state、getters、actions(移除mutation) 深度对比 Pinia 与 Vuex:新一代状态管理方案的核心差异 一、核心架构设计对比 维度VuexPinia设计目标集…...
路由交换网络专题 | 第七章 | BGP练习 | 次优路径 | Route-Policy | BGP认证
基本部分配置讲解: 配置BGP相关部分: // BGP区域配置: 用作环回口创建BGP对等体// “ipv4-family unicast”是指进入BGP的IPv4单播地址族视图。 // 配置完后仅仅只在IPV4地址簇下建立对等体。* [AR3]bgp 100 [AR3-bgp]peer 1.1.1.1 as-number 100 [AR…...
序论文42 | patch+MLP用于长序列预测
论文标题:Unlocking the Power of Patch: Patch-Based MLP for Long-Term Time Series Forecasting 论文链接:https://arxiv.org/abs/2405.13575v3 代码链接:https://github.com/TangPeiwang/PatchMLP (后台回复“交流”加入讨…...
【mongodb】系统保留的数据库名
目录 1. admin2. config3. local4. test(非严格保留,但常作为默认测试数据库)5. 注意事项6. 其他相关说明 1. admin 1.用途:用于存储数据库的权限和用户管理相关数据。2.特点:该数据库是 MongoDB 的超级用户数据库&am…...
js 的call 和apply方法用处
主要用于ECMAScript与宿主环境(文档对象(DOM)、浏览器对象(BOM))的交互中; 例子:function changeStyle(attr, value){ this.style[attr] value; } …...
济南国网数字化培训班学习笔记-第二组-2节-输电线路施工及质量
输电线路施工及质量 质量管控基本规定 基本规定 项目分类 土石方(测量挖坑)、基础、杆塔、架线、接地、线路防护 检验项目分类原则: 1.主控项目:影响工程性能、强度、安全性和可靠性,且不易修复和处理 2.一般项…...
“Daz to Unreal”将 G8 角色(包括表情)从 daz3d 导入到 UE5。在 UE5 中,我发现使用某个表情并与闭眼混合后,上眼睑出现了问题
1) Bake & Export Corrective Morphs from Daz before you go into UE5 1) 在进入 UE5 之前,从 Daz 烘焙并导出修正型变形 In Daz Studio 在 Daz Studio 中 Load your G8 head, dial in the exact mix (e.g. Smile 1.0 Eyes Closed 1.0). 加载你的 G8 头部&am…...
Linux系统之----进程优先级、调度与切换
在开启本篇文章的学习之前,我们先要熟悉如下两个事 1.概念 进程优先级指的是进程能得到某种资源的先后顺序,要理解好它与权限的关系,优先级是 能,拥有资源的先后顺序,权限是 能还是不能的问题 2.为什么要有优先级…...
Web3钱包开发功能部署设计
Web3钱包开发功能部署设计全景指南(2025技术架构与实战) ——从核心模块到多链生态的完整解决方案 一、核心功能模块设计 1.1 资产管理体系 Web3钱包的核心功能围绕资产存储、交易验证、多链兼容展开: • 密钥管理:…...
【含文档+PPT+源码】基于SpringBoot的开放实验管理平台设计与实现
项目介绍 本课程演示的是一款基于SpringBoot的开放实验管理平台设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...
小刚说C语言刷题——1317正多边形每个内角的度数?
1.题目描述 根据多边形内角和定理,正多边形内角和等于:( n-2 ) 180∘ ( n 大于等于 3且 n 为整数) 请根据正多边形的边数,计算该正多边形每个内角的度数。(结果保留1位小数&#x…...
Spring—AOP
AOP是在不惊动原有的代码的基础上对功能进行增强操作 连接点:JoinPoint,可以被AOP控制的方法 通知:Advice,增强的逻辑,共性功能 切入点:PointCut,匹配连接点的条件,表明连接点中哪…...
算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II、区间和
209.长度最小的子数组 题目 思路与解法 **第一想法:**无 carl的讲解: 滑动窗口 class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:ij0lens len(nums)sum 0res lens 1while j < lens:# for m in range(i, j1)…...
【C++ 真题】P3456 [POI2007] GRZ-Ridges and Valleys
[POI2007] GRZ-Ridges and Valleys 题面翻译 题目描述 译自 POI 2007 Stage 2. Day 0「Ridges and Valleys」 给定一个 n n n \times n nn 的网格状地图,每个方格 ( i , j ) (i,j) (i,j) 有一个高度 w i j w_{ij} wij。如果两个方格有公共顶点,…...
Vue3 中 computed的详细用法
Vue 3 中 computed 是一个非常重要的响应式 API,它是基于其依赖项的值来计算得出的值,当依赖项发生变化时,计算属性会自动更新 基本用法 在选项式 API 中,computed 通常作为一个选项直接在组件的选项对象中定义。例如 <temp…...
位带和位带别名区
位带区域和位带别名区域 位带区域(Bit-banding)是一种技术, 允许开发者直接访问和修改内存中的单个位。 这种技术在某些微控制器(如ARM Cortex-M系列)中特别有用,因为它可以简化对寄存器位的访问和修改。 …...
DRF凭什么更高效?Django原生API与DRF框架开发对比解析
一、原生 Django 开发 API 的局限性 虽然 Django 可以通过 JsonResponse 和视图函数手动构建 API,但存在以下问题: 手动序列化与反序列化 需要手动将模型实例转换为 JSON,处理复杂数据类型(如嵌套关系)时代码冗长且易…...
Agent智能体应用详解:从理论到实践的技术探索
一、Agent智能体是什么? 1. 核心定义 Agent智能体是能够感知环境、自主决策并执行动作以实现目标的软件实体。其核心特征包括: 自主性:无需外部指令持续运行。 反应性:实时响应环境变化。 目标导向:基于预设或学习…...
Windows下使用 VS Code + g++ 开发 Qt GUI 项目的完整指南
🚀 使用 VS Code g 开发 Qt GUI 项目的完整指南(Windows MSYS2) 本指南帮助你在 Windows 下使用 VS Code g CMake Qt6 快速搭建 Qt GUI 项目,适合熟悉 Visual Studio 的开发者向跨平台 VS Code 工具链迁移。 🛠️…...
arm64适配系列文章-第三章-arm64环境上mariadb的部署
ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...
YOLOv8融合CPA-Enhancer【提高恶略天气的退化图像检测】
1.CPA介绍 CPA-Enhancer通过链式思考提示机制实现了对未知退化条件下图像的自适应增强,显著提升了物体检测性能。其插件式设计便于集成到现有检测框架中,并在物体检测及其他视觉任务中设立了新的性能标准,展现了广泛的应用潜力。 关于CPA-E…...
编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)
前言 在使用终端编译 C 程序时,报错: 或类似提示,意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g,适用于新手或 C 入门阶段的你。 什么是 g? g 是 GN…...
Spring 过滤器详解:从基础到实战应用
Spring 过滤器详解:从基础到实战应用 引言 在 Spring 框架中,过滤器(Filter)是处理 HTTP 请求和响应的重要组件。它们为开发者提供了一种在请求到达控制器之前或响应返回客户端之前进行操作的机制。本文将深入探讨 Spring 中常见…...
达梦并行收集统计信息
达梦收集统计信息速度如何? 答:1分钟1G 大库收集起来可能比较慢,想并行收集需要一些条件 3个参数先了解一下 我把max_parallel_degree改为16 相关说明可以看一下 对一个3G的表收集 收集方法 DBMS_STATS.GATHER_TABLE_STATS( TEST,T1,…...
AOSP CachedAppOptimizer 冻结方案
背景 Android 一直面临一个核心难题:如何优化进程对有限系统资源(如 CPU、电量)的使用,同时保证用户体验。 当进程进入后台后,它们虽不再贡献用户体验,却仍可能消耗资源。传统的杀后台方案虽然节省资源&a…...
JVM-类加载机制
类加载 前言:为什么需要了解类加载?什么是类加载?生命周期概览类加载过程详解3.1 加载 (Loading)3.2 连接 (Linking)3.2.1 验证 (Verification)3.2.2 准备 (Preparation)3.2.3 解析 (Resolution) 3.3 初始化 (Initialization)3.3.1 <clini…...
【小白福音】SFTP限制权限登录
下面以在 Linux 环境(例如 Ubuntu 或 CentOS)上配置 SFTP chroot 为例,给出详细的步骤说明。即使你不熟悉服务器运维,也可以按照以下步骤进行配置,保证指定的 SFTP 用户只能访问预设目录,而无法触碰其他文件。 目录 一、配置SFTP权限1. 创建专用 SFTP 用户和用户组2. 搭建…...
海量数据笔试题--Top K 高频词汇统计
问题描述: 假设你有一个非常大的文本文件(例如,100GB),文件内容是按行存储的单词(或其他字符串,如 URL、搜索查询词等),单词之间可能由空格或换行符分隔。由于文件巨大&…...
Postman设置环境变量与Token
设置环境变量 设置某个Collection下的变量...
项目中数据结构为什么用数组,不用List
总结 1,从内存和性能角度,数组占用更小的内存(),访问性能更高() 分配效率:数组在内存中是连续分配的一块固定空间 访问速度:直接操作内存,数组的读写操作是…...
Linux常见指令介绍下(入门级)
1. head head就和他的名字一样,是显示一个文件头部的内容(会自动排序),默认是打印前10行。 语法:head [参数] [文件] 选项: -n [x] 显示前x行。 2. tail tail 命令从指定点开始将文件写到标准输出.使用t…...
从Kafka读取数据
用Spark-Streaming从Kafka读取数据 在大数据处理领域,Spark-Streaming和Kafka都是明星技术。今天咱们就来聊聊怎么用Spark-Streaming从Kafka读取数据并做处理,就算你是小白,也保证能看懂!先讲讲从Kafka获取数据的两种方式。早期有…...
硬件工程师面试常见问题(7)
第三十一问:RTC电路,电池寿命估算 上图可知,该电路有两个供电一个是电池供电,一个是其他供电,已知电池大小为120mAh,该电路在电池供电下吃3uA的电流,计算 120*(10^3)/ 3…...
二分小专题
P1102 A-B 数对 P1102 A-B 数对 暴力枚举还是很好做的,直接上双层循环OK 二分思路:查找边界情况,找出最大下标和最小下标,两者相减1即为答案所求 废话不多说,上代码 //暴力O(n^3) 72pts // #include<bits/stdc.h> // usin…...
Explain详解与索引最佳实践
Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL 注意…...
【Qt6 QML Book 基础】07:布局项 —— 锚定布局与动态交互(附完整可运行代码)
引言 在 QML 界面开发中,** 锚定布局(Anchors)** 是实现响应式设计的核心机制。通过声明式的锚定规则,开发者无需手动计算坐标,即可让元素与父容器或其他元素保持动态位置关联。本文结合官方示例,详细解析…...
rocky9.4部署k8s群集v1.28.2版本(containerd)(纯命令)
文章目录 前言三个节点的主机名 所有节点操作主机名和ip解析关闭交换分区,关闭防火墙,关闭selinux更换阿里云yum源时间同步修改内核参数修改系统最大打开文件数开启bridge网桥过滤,加载br_netfilter模块,加载配置文件安装ipset及i…...
Crawl4AI 部署安装及 n8n 调用,实现自动化工作流(保证好使)
Crawl4AI 部署安装及 n8n 调用,实现自动化工作流(保证好使) 简介 Crawl4AI 的介绍 一、Crawl4AI 的核心功能 二、Crawl4AI vs Firecrawl Crawl4AI 的本地部署 一、前期准备 二、部署步骤 1、检查系统的网络环境 2、下载 Crawl4AI 源…...
onlyoffice8.3.3发布了-豆豆容器市场同步更新ARM64版本
8.3.3 修复内容 文档编辑器 • 修复从右到左(RTL)段落的计算问题 (DocumentServer#2590) • 修复从右到左段落中"项目符号/编号/多级列表"样式缩略图的显示问题 • 修复从右到左段落中编号列表(项目符号)的显示问题 (…...
rabbitmq安装项目集成
使用Docker来安装 1.1.下载镜像 docker pull rabbitmq:3-management 1.2.安装MQ docker run \-e RABBITMQ_DEFAULT_USER=root \-e RABBITMQ_DEFAULT_PASS=123123 \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management 15672:RabbitMQ提供…...
济南国网数字化培训班学习笔记-第二组-3节-电网工程建设项目部门
电网工程建设项目部 组成 监理项目部 履行监理合同,监理单位派驻:负责合同管理,审查,见证,旁站,巡视,验收,控制进度,安全,质量,协调各方 造价…...
JDK(java)安装及配置 --- app笔记
JDK官方下载地址:Java Downloads | Oracle 安装好后,配置 “环境变量”: 新建JAVA_HOME变量,值为 jdk 安装 根目录(C:\Program Files\Java\jdk-24) 在path变量最后面,添加 %JAVA_HOME% 新建 CLA…...
【前端】【面试】在前端开发中,如何优化 CSS 以提升页面渲染性能?
题目:在前端开发中,如何优化 CSS 以提升页面渲染性能? 关键词总结 关键词说明选择器优化避免通配符、减少层级深度、防止后代选择器过度嵌套样式规则优化合并重复规则、慎用高成本属性加载与渲染优化关键 CSS 优先加载、合理使用媒体查询文…...
python的mtcnn检测图片中的人脸并标框
python的mtcnn检测图片中的人脸并标框,标记鼻尖位置 import cv2 from mtcnn import MTCNN# 初始化 MTCNN 检测器 # stages:指定检测阶段 # 指定运行设备为CPU detector MTCNN(stages"face_and_landmarks_detection", device"CPU:0"…...
矩阵系统源码搭建账号分组功能开发全流程解析,支持OEM
在短视频矩阵运营场景下,企业和创作者往往管理着数十甚至上百个不同平台的账号,传统的统一管理模式效率低下,难以满足精细化运营需求。矩阵系统的账号分组功能通过对账号进行分类整合,实现差异化管理与精准化操作。本文将从功能需…...
跟着deepseek学golang--认识golang
文章目录 一、Golang核心优势1. 极简部署方式生产案例:依赖管理:容器实践: 2. 静态类型系统类型安全示例:性能优势:代码重构: 3. 语言级并发支持GMP调度模型实例&…...
如何创建极狐GitLab 议题?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 创建议题 (BASIC ALL) 创建议题时,系统会提示您输入议题的字段。 如果您知道要分配给议题的值,则可…...
制造工厂如何借助电子看板实现高效生产管控
在当今高度竞争的制造业环境中,许多企业正面临着严峻的管理和生产挑战。首先,管理流程落后,大量工作仍依赖"人治"方式,高层管理者理论知识薄弱且不愿听取专业意见。其次,生产过程控制能力不足,导…...
QLExpress 深度解析:构建动态规则引擎的利器
QLExpress 深度解析:构建动态规则引擎的利器 在现代业务系统中,“规则变更快、逻辑复杂、发布要求高”已成为常态。传统硬编码已无法满足这种需求。本文以阿里巴巴开源的轻量级表达式引擎 QLExpress 为例,从实际应用、核心结构到落地建议,系统解析其强大能力和设计哲学。 …...