各数据库千万级数据构造

前提

领导希望看到平台支持的各种数据库在大数据量的情况分页,查询的情况,所以就有了前提工作,准备构造千万级的数据,在网上找了各种数据库别人构造的文档,后面整理了这篇。

一、sqlserver

declare  @i int
declare  @j int
set  @i = 1
while @i <= 1000
begin
set  @j = 1
begin  tran 
while @j <= 10000
begin
insert into
   [zlyTest].[dbo].[SS_TYPE](test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15,test16,test17,test18,test19) values(1,'1','1','2021-04-14 10:23:03','2021-04-14 10:23:06','2021-04-14 10:23:08',1.1,1.1,1,'1','1','1',1,'1','2021-04-14 10:23:29',1,'1','1','1')
set  @j = @j + 1 
end
commit tran
set @i = @i + 1
end
执行结果

按1万条提交一次,1000万大约要50分钟

二、mysql

DROP PROCEDURE IF EXISTS proc_buildata;
DROP PROCEDURE IF EXISTS proc_buildata_fast;

CREATE PROCEDURE proc_buildata(IN loop_times INT)
BEGIN
        DECLARE var INT DEFAULT 0;
        SET AUTOCOMMIT=0;
        START TRANSACTION;
        WHILE var<loop_times DO
                SET var=var+1;
                INSERT INTO ZLYTEST.SS_TYPE (test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15,test16,test17,test18,test19,test20,test21,test22,test23,test24,test25) VALUES (1,'1','1','1','2021-04-14 00:00:00','2021-04-14 11:01:08',1,1.1,1,1,1,'1','1','1','1','1',1,1,'1','1970-01-01 11:01:28','2021-04-14 11:01:32','1',1,'1','1');
        END WHILE;
        COMMIT;
        SET AUTOCOMMIT=1;
END;

CREATE PROCEDURE proc_buildata_fast(IN loop_times INT)
BEGIN
        DECLARE single_max INT DEFAULT 100000;
        DECLARE i INT DEFAULT 0;
        DECLARE max INT DEFAULT 0;
        SET max=loop_times/single_max;
        SET i=0;
        WHILE i<max DO
                SET i=i+1;
                CALL proc_buildata(single_max);
        END WHILE;
END;

CALL proc_buildata_fast(10000000);
执行结果

按10万条提交一次,1000万大约要91分钟

三、oracle

declare
i integer; --定义变量
begin
i := 1;
loop
/* 插入数据 */
 INSERT INTO SS_TYPE (test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15,test16) VALUES ('1','1','1',to_date('2021-04-14 11:21:11' , 'yyyy-mm-dd hh24:mi:ss'),1.1,1.1,1,1,'1',1.1,1.1,'1',1,to_date('2021-04-14 11:21:20' , 'yyyy-mm-dd hh24:mi:ss'),'1','1');
/* 参数递增 */
i := i + 1;
/* 停止条件 */
exit when i > 10000000;
end loop;
commit;
end;

四、达梦

DECLARE
 i int :=1;
BEGIN
   FOR i IN 1..10000000 LOOP
 INSERT INTO "ss_type"(COLUMN_1,COLUMN_2,COLUMN_3,COLUMN_4,COLUMN_5,COLUMN_6,COLUMN_7,COLUMN_8,COLUMN_9,COLUMN_10,COLUMN_11,COLUMN_12,COLUMN_13,COLUMN_14,COLUMN_15,COLUMN_16,COLUMN_17,COLUMN_18,COLUMN_19) VALUES ('1','1','1',1.1,1.1,1.1,1,1,1,1,1,1.1,1.1,'2021-04-14 14:11:06','2021-04-14 14:11:03','2021-04-14 14:11:05','2021-04-14 14:11:01','1','1');
   END LOOP;
END;
COMMIT

执行时间

1000万大约要15分钟

五、人大金仓

CREATE OR REPLACE PROCEDURE proc_buildata() AS
DECLARE
v_id integer :=1;
BEGIN
FOR i IN 1..100000 LOOP
INSERT INTO "ss_type"(test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15,test16,test17,test18,test19,test20,test21,test22) VALUES ('1','1','2021-04-14 11:45:28','2021-04-14 11:45:26','2021-04-14 11:45:30',1,1,1,1,1,1,1,1.1,1.1,1.1,'1','1','1',false,1,1,'1');
v_id := v_id+1;
END LOOP;
END;
CALL proc_buildata();

六、神通

declare
i integer; --定义变量
begin
i := 1;
loop
/* 插入数据 */
 INSERT INTO "SS_TYPE"(COLUMN1,COLUMN4,COLUMN7,COLUMN8,COLUMN9,COLUMN10,COLUMN11,COLUMN18,COLUMN19,COLUMN20,COLUMN21,COLUMN22,COLUMN23,COLUMN24,COLUMN25,COLUMN26,COLUMN27) VALUES('1','1','1','1','2021-04-14 11:45:28',1.1,1.1,'1',1.1,1.1,1.1,1,'1','2021-04-14 11:45:26','2021-04-14 11:45:30','1','1');
/* 参数递增 */
i := i + 1;
/* 停止条件 */
exit when i > 100000;
end loop;
commit;
end;

<think>好的,我现在需要帮用户解答关于PostgreSQL数据库中去重统计数量的问题。首先,用户之前问过“value too long for type character varying(3)”的错误,现在转向另一个问题,可能是他们在处理数据时遇到了重复数据,需要统计去重后的数量。我需要确定用户的具体需求是什么,他们可能是在处理数据分析、报表生成或者数据清洗的场景。 首先,用户提到的“去重统计数据量”应该是指统计某个字段或组合字段的唯一值数量。在PostgreSQL中,常用的方法是使用COUNT(DISTINCT column)。但可能用户的数据量很大,需要考虑性能优化,或者他们需要更复杂的去重方式,比如多列组合去重,或者使用窗口函数。 接下来,我需要回顾PostgreSQL的去重方法,确保覆盖基本用法和高级技巧。比如,COUNT(DISTINCT)在数据量大时可能效率不高,这时候可能需要使用子查询或者临时表来优化。另外,如果用户需要统计多列组合的唯一性,可能需要使用CONCAT或者更高效的方法,比如行构造函数。 然后,还要考虑用户是否有大数据量的情况,这时候可能需要分析执行计划,添加索引,或者使用近似估算函数如hyperloglog来加快统计速度。用户可能没有提到性能问题,但作为全面解答,应该涵盖这些方面。 同时,用户之前遇到的字段长度问题,可能在数据清洗阶段需要去重,比如去除重复记录前需要先处理字段超长的问题。因此,可能需要结合之前的解决方案,比如在清理数据后进行去重统计。 还要注意用户是否是开发者或者DBA,可能需要不同的技术细节层次。比如,开发者可能需要具体的SQL示例,而DBA可能更关注性能调优和索引策略。 最后,确保回答结构清晰,分步骤说明,并给出实际例子,帮助用户逐步解决问题。同时提醒注意事项,比如索引的使用、数据量对性能的影响,以及近似方法的适用场景。</think>--- ### **PostgreSQL 去重统计数量详解** 在 PostgreSQL 中,"去重统计"通常指统计某一列(或多列组合)的唯一值数量。以下是 **4 种核心方法**及其适用场景: --- ### **1. 基础去重统计** #### **语法** ```sql SELECT COUNT(DISTINCT 列名) AS 唯一值数量 FROM 表名; ``` #### **示例** 统计 `employees` 表中不同部门的数量: ```sql SELECT COUNT(DISTINCT department) AS dept_count FROM employees; ``` #### **特点** - 简单直接 - 适合单列去重 - 数据量大时可能较慢(需全表扫描) --- ### **2. 多列组合去重** #### **语法** ```sql SELECT COUNT(*) AS 唯一组合数量 FROM ( SELECT DISTINCT 列1, 列2, 列3 FROM 表名 ) AS subquery; ``` #### **示例** 统计 `orders` 表中客户与产品的唯一组合数量: ```sql SELECT COUNT(*) AS unique_pairs FROM ( SELECT DISTINCT customer_id, product_id FROM orders ) AS tmp; ``` #### **优化技巧** - 使用行构造函数提高效率: ```sql SELECT COUNT(DISTINCT (customer_id, product_id)) FROM orders; ``` --- ### **3. 高性能统计方法** #### **(1) 预聚合统计** ```sql -- 创建物化视图定期刷新 CREATE MATERIALIZED VIEW stats_unique_users AS SELECT COUNT(DISTINCT user_id) FROM log_table; ``` #### **(2) 近似统计(海量数据推荐)** 使用 `hyperloglog` 扩展: ```sql CREATE EXTENSION hll; SELECT hll_cardinality(hll_add_agg(hll_hash_text(列名))) FROM 表名; ``` 误差约 **0.8%**,但速度提升 **10-100 倍**。 --- ### **4. 分区统计技巧** #### **按时间范围分段统计** ```sql SELECT date_trunc('day', created_at) AS day, COUNT(DISTINCT user_id) AS dau FROM events GROUP BY 1 ORDER BY 1; ``` #### **分类分层统计** ```sql WITH ranked_data AS ( SELECT product_id, ROW_NUMBER() OVER(PARTITION BY product_id ORDER BY created_at) AS rn FROM sales ) SELECT COUNT(*) FROM ranked_data WHERE rn = 1; ``` --- ### **性能优化指南** | 方法 | 适用场景 | 数据量上限 | 速度 | |---------------------|----------------------------|--------------|----------| | `COUNT(DISTINCT)` | 常规去重 | < 1000万行 | 中等 | | 子查询去重 | 多列组合统计 | < 5000万行 | 较慢 | | 物化视图 | 高频查询的固定统计 | 无上限 | 瞬时返回 | | HyperLogLog | 允许误差的海量数据 | > 1亿行 | 极快 | --- ### **常见问题解决** #### **问题 1:统计结果不准确** - 检查是否有 NULL 值:`COUNT(DISTINCT)` 会自动忽略 NULL - 处理空白值:`COUNT(DISTINCT NULLIF(trim(列名), ''))` #### **问题 2:统计速度过慢** 1. 添加表达式索引: ```sql CREATE INDEX idx_gin ON 表名 USING GIN (列名 gin_trgm_ops); ``` 2. 并行查询优化: ```sql SET max_parallel_workers_per_gather = 4; ``` --- ### **进阶用法** #### **实时唯一用户统计** ```sql -- 使用位图加速统计 SELECT COUNT(DISTINCT user_id) FILTER (WHERE event_type = 'click'), COUNT(DISTINCT user_id) FILTER (WHERE event_type = 'view') FROM user_events; ``` #### **滑动窗口去重** ```sql SELECT day, COUNT(DISTINCT user_id) OVER (ORDER BY day ROWS 6 PRECEDING) FROM daily_stats; ``` --- 通过合理选择统计方法+索引优化+预处理,可高效完成从百万到百亿级数据的去重统计。建议: 1. 百万级数据直接使用 `COUNT(DISTINCT)` 2. 千万级数据尝试预聚合 3. 亿级以上使用 HyperLogLog 或采样统计
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值