yjhatfdu2 最近的时间轴更新
yjhatfdu2

yjhatfdu2

V2EX 第 457268 号会员,加入于 2019-12-04 10:30:20 +08:00
yjhatfdu2 最近回复了
10 天前
回复了 ihnfsa 创建的主题 云计算 自建数据湖方案
其实现在技术上几种数据糊技术核心的目的是解决传统 hadoop 系统中,parquet 等列存格式,难以支持 ACID 和事务的问题
10 天前
回复了 ihnfsa 创建的主题 云计算 自建数据湖方案
数据糊技术显然是为了写入和低成本优化的,查询速度会慢的离谱(正常场景下),例如使用 apache hudi ,即使使用了记录级索引,在 1TB20 亿行数据中使用索引取一行也要 12 秒,取 40000 行要 115 秒(来源 https://hudi.apache.org/blog/2023/11/01/record-level-index/),这在 RAG 的场景中简直是离谱
11 天前
回复了 ihnfsa 创建的主题 云计算 自建数据湖方案
开源数据糊一般是指 apache hudi 、apache iceberg 和 delta lake ,但这玩意儿都还是适合写入为主,偶尔批量计算的场景,不适合实时查询,和 AI Agent 、RAG 有啥关系?
find . -name '*.csv.gz' | xargs -I {} -P 4 bash -c "gzcat {} | psql -c 'copy test from stdin csv header'"
P 是并发,可以开高点
31 天前
回复了 zdking08135 创建的主题 程序员 请教一个系统设计题
@zdking08135 当然可以,不过按照这个编码形式,肯定要指定 country
32 天前
回复了 zdking08135 创建的主题 程序员 请教一个系统设计题
clickhouse 造一天数据试试看,单机 64 核 epyc 256G ram
建表,目前试下来效率最高的表结构
create table test4
(
time datetime CODEC (DoubleDelta, LZ4),
country UInt8 CODEC (DoubleDelta, LZ4),
province UInt8 CODEC (DoubleDelta, LZ4),
city UInt16 CODEC (DoubleDelta, LZ4),
uid UInt32
) engine = MergeTree() partition by toYYYYMMDD(time)
order by (time, country, province, city) settings index_granularity = 65536;

先造 10 亿数据,分布在一天内
insert into test4
select dateAdd(second, number / 1000000000, toDateTime('2024-04-02'))
, rand32() % 200
, rand32(1) % 250
, rand32(2) % 100
, number + 1
from numbers(1000000000);
-- 然后扩增到 32 倍
insert into test4 select * from test4;
insert into test4 select * from test4;
insert into test4 select * from test4;
insert into test4 select * from test4;
insert into test4 select * from test4;

SELECT count(*)
FROM test4

Query id: a4a01197-a22b-4a0d-9747-26555229ff58

┌─────count()─┐
│ 32000000000 │
└─────────────┘

1 row in set. Elapsed: 0.004 sec.
一共 320 亿
等后台 merge 完才 14.28 GiB 磁盘占用
楼主要的查询
WITH r AS
(
SELECT count() AS c
FROM test4
WHERE country = 100
GROUP BY uid
)
SELECT avg(c)
FROM r

Query id: c634e7a7-13fa-4d40-9f30-e6e43105ffe9

┌─avg(c)─┐
│ 32 │
└────────┘

1 row in set. Elapsed: 0.168 sec. Processed 160.30 million rows, 801.18 MB (954.12 million rows/s., 4.77 GB/s.)
0.168 秒完成

这样看起来,一年的数据单机也问题不大
注意,不同的建表语句尤其是 CODEC 非常影响存储空间和性能
32 天前
回复了 zdking08135 创建的主题 程序员 请教一个系统设计题
这个量,clickhouse 集群,做好表的设计,选好排序键、字段编码和压缩,按天分区,这个量写入和查询问题应该都不是很大。顺便,兄弟你这是在做天网么
@woodytang pg 下,如果可以用程序生成返回列然后拼接 SQL ,那么很简单
//创建测试表
create table test3("user" text,amount int,datetime timestamp);
insert into public.test3 (user, amount, datetime)
values ('A', 10, '2021-02-12 10:00:00.000000'),
('A', 20, '2021-03-12 10:00:00.000000'),
('B', 30, '2021-05-12 10:00:00.000000'),
('B', 10, '2021-06-12 10:00:00.000000'),
('C', 10, '2021-06-12 10:00:00.000000'),
('C', 20, '2021-06-12 10:00:00.000000'),
('C', 5, '2021-05-12 10:00:00.000000');
//使用 crosstab 进行 pivot
select *
from crosstab($$select "user",date_trunc('month',datetime)::date::text,sum(amount)
from test3 group by 1,2 order by 1,2 $$,
'select distinct date_trunc(''month'',datetime)::date::text from test3 order by 1') as ct(
"user" text,
"2021-02" text,
"2021-03" text,
"2021-05" text,
"2021-06" text
);
//结果
user | 2021-02 | 2021-03 | 2021-05 | 2021-06
------+---------+---------+---------+---------
A | 10 | 20 | |
B | | | 30 | 10
C | | | 5 | 30

如果要动态生成返回列名,那么确实是相当的麻烦,因为 pg 的查询必须显式制定列,只能用非常别扭的方式
-- 创建一个函数,实际查询的 SQL ,可以反复使用
create or replace function crosstabquery(_t anyelement) returns setof anyelement as
$$
declare
column_list text;
begin
select string_agg(format('%I text', d), ',')
into column_list
from (select distinct date_trunc('month', datetime)::date::text d from test3 order by 1) r;
return query execute ($b$select *
from crosstab($a$select "user",date_trunc('month',datetime)::date::text,sum(amount)
from test3 group by 1,2 order by 1,2 $a$,
'select distinct date_trunc(''month'',datetime)::date::text from test3 order by 1') as ct("user" text,$b$ ||
column_list||')' );
end ;
$$
language plpgsql;
-- 创建返回类型,每次使用前调用
do
$$
declare
column_list text;
begin
select string_agg(format('%I text', d), ',')
into column_list
from (select distinct date_trunc('month', datetime)::date::text d from test3 order by 1) r;
drop type if exists __t;
execute format('create type __t as ("user" text, %s)', column_list);
end
$$ language plpgsql;
-- 返回实际结果
select * from crosstabquery(null::__t);
user | 2021-02-01 | 2021-03-01 | 2021-05-01 | 2021-06-01
------+------------+------------+------------+------------
A | 10 | 20 | |
B | | | 30 | 10
C | | | 5 | 30
(3 rows)

不过如果可以动态生成 sql ,就别用下面这个方案,实在是别扭
这不是一句 sql 查询就能解决的事情吗,为啥要变复杂?
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2568 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 12:56 · PVG 20:56 · LAX 05:56 · JFK 08:56
Developed with CodeLauncher
♥ Do have faith in what you're doing.