欢迎光临
我们一直在努力

clickhouse 26.6和duckdb 1.6dev的group by cube查询比较

对1亿行随机数分组汇总
duckdb 1.6dev

C:\\d>duckdb0619
DuckDB v1.6.0dev9098 (Development Version, 2bfea2aa19)
Enter ".help" for usage hints.
memory D create table ren as select
((random()*1000)::int%2+1)::int c1,
((random()*1000)::int%100+1)::int c2,
((random()*1000)::int%30+1)::int c3,
((random()*1000)::int%60+1)::int c4,
((random()*1000)::int%5+1)::int c5
from generate_series(1,1e8::int);
memory D .timer on
memory D create table rc1c2c3c4 as select c1,c2,c3,c4,sum(1)cnt from ren group by cube(c1,c2,c3,c4);
Run Time (s): real 1.593 user 17.390625 sys 0.968750
memory D select count(*) from rc1c2c3c4;
┌──────────────┐
│ count_star()
│ int64 │
├──────────────┤
572973
└──────────────┘
Run Time (s): real 0.010 user 0.000000 sys 0.000000

clickhouse 26.6

C:\\d>wsl
root@DESKTOP59T6U68:/mnt/c/d# ./clickhouse
ClickHouse local version 26.6.1.731 (official build).

:) create table ren as select
((rand()*1000)::int%2+1)::int c1,
((rand()*1000)::int%100+1)::int c2,
((rand()*1000)::int%30+1)::int c3,
((rand()*1000)::int%60+1)::int c4,
((rand()*1000)::int%5+1)::int c5
from generate_series(1,100000000);

CREATE TABLE ren
AS SELECT
CAST(((CAST((rand() * 1000), 'int') % 2) + 1), 'int') AS c1,
CAST(((CAST((rand() * 1000), 'int') % 100) + 1), 'int') AS c2,
CAST(((CAST((rand() * 1000), 'int') % 30) + 1), 'int') AS c3,
CAST(((CAST((rand() * 1000), 'int') % 60) + 1), 'int') AS c4,
CAST(((CAST((rand() * 1000), 'int') % 5) + 1), 'int') AS c5
FROM generate_series(1, 100000000)

Query id: e6a83d26e6a940ba8eedb74f285fbc78

Ok.

100000000 rows in set. Elapsed: 5.758 sec. Processed 100.00 million rows, 800.00 MB (17.37 million rows/s., 138.94 MB/s.)
Peak memory usage: 63.47 MiB.

:) create table rc1c2c3c4 as select c1,c2,c3,c4,sum(1)cnt from ren group by cube(c1,c2,c3,c4);

CREATE TABLE rc1c2c3c4
AS SELECT
c1,
c2,
c3,
c4,
sum(1) AS cnt
FROM ren
GROUP BY
c1,
c2,
c3,
c4
WITH CUBE

Query id: b2eca8f332f246689786d69cfd038f53

Ok.

1168 rows in set. Elapsed: 0.322 sec. Processed 100.00 million rows, 1.60 GB (310.67 million rows/s., 4.97 GB/s.)
Peak memory usage: 4.09 MiB.

与duckdb比较,clickhouse生成数据和汇总都快得出奇,但后者的行数明显过少,查看数据。

:) select * from ren;

SELECT *
FROM ren

Query id: a402aca9009b439997705bf3123b31db

┌─c1─┬──c2─┬──c3─┬──c4─┬─c5─┐
1.1577372
2.147772
3.1313433
4.159111
5.15525550
6.1121211
7.1755350
8.19313133
9.1977372
10.161111
11.159111
12.181111
13.1525255
14.12313433

4227068.14919494
4227069.1525255
4227070.1311311
4227071.1933333
4227072.17727572
└─c1─┴──c2─┴──c3─┴──c4─┴─c5─┘
Showed 1000 out of 100000000 rows.

100000000 rows in set. Elapsed: 0.497 sec. Processed 100.00 million rows, 2.00 GB (201.16 million rows/s., 4.02 GB/s.)
Peak memory usage: 188.60 MiB.

:) select * from rc1c2c3c4 limit 10;

SELECT *
FROM rc1c2c3c4
LIMIT 10

Query id: c892b34d8eb446cd811ececddf035987

┌─c1─┬─c2─┬─c3─┬─c4─┬────cnt─┐
1.1931313667216
2.1812121666623
3.14111665197
4.1555666132
5.192929666747
6.1771717666084
7.152525666766
8.1892929666258
9.18555667259
10.14999666100
└────┴────┴────┴────┴────────┘

10 rows in set. Elapsed: 0.005 sec. Processed 1.17 thousand rows, 28.03 KB (217.09 thousand rows/s., 5.21 MB/s.)
Peak memory usage: 39.17 KiB.

:)

:) select rand();

SELECT rand()

Query id: 5000b861343a4e26b35c0f40e4c66415

┌─────rand()─┐
1.4067771733— 4.07 billion
└────────────┘

1 row in set. Elapsed: 0.003 sec.

create table ren as select
(rand()%2+1)::int c1,
(rand()%100+1)::int c2,
(rand()%30+1)::int c3,
(rand()%60+1)::int c4,
(rand()%5+1)::int c5
from generate_series(1,100000000);

CREATE TABLE ren
AS SELECT
CAST(((rand() % 2) + 1), 'int') AS c1,
CAST(((rand() % 100) + 1), 'int') AS c2,
CAST(((rand() % 30) + 1), 'int') AS c3,
CAST(((rand() % 60) + 1), 'int') AS c4,
CAST(((rand() % 5) + 1), 'int') AS c5
FROM generate_series(1, 100000000)

Query id: 8907c2c13cb24903a0a1d350a8407d36

Ok.

100000000 rows in set. Elapsed: 5.601 sec. Processed 100.00 million rows, 800.00 MB (17.85 million rows/s., 142.84 MB/s.)
Peak memory usage: 63.60 MiB.

:) select * from ren limit 20;

SELECT *
FROM ren
LIMIT 20

Query id: 8e3d2756a3b34814b84ddbc199c1fa95

┌─c1─┬─c2─┬─c3─┬─c4─┬─c5─┐
1.22616461
2.14919494
3.15323533
4.2424244
5.27818183
6.26212422
7.1313433
8.161111
9.2212422
10.12919494
11.1933333
12.23626561
13.13525555
14.246661
15.13929594
16.284444
17.22818483
18.2522322
19.24010405
20.12717472
└────┴────┴────┴────┴────┘

20 rows in set. Elapsed: 0.005 sec.

:)
:) select rand(),rand();

SELECT
rand(),
rand()

Query id: 1af2ae02cec747038bd32466b67260da

┌─────rand()─┬─────rand()─┐
1.35902680323590268032— 3.59 billion
└────────────┴────────────┘

负数是整数乘法溢出的结果,rand()返回32位整数,去掉多余的*1000,看出问题了,对20, 60, 100取模的结果都一样,原因是clickhouse在同一行多次调用rand(),返回同一个值,所以从c1到c5, 它们的值都是固定的函数关系,导致分组过少。
而duckdb的同一行多个random()返回不同的值。

memory D select random(),random();
┌─────────────────────┬────────────────────┐
│ random() │ random()
doubledouble
├─────────────────────┼────────────────────┤
0.465927178382777030.7400053681100808
└─────────────────────┴────────────────────┘

暂时没找到方法让clickhouse返回不同的值。先把duckdb数据表复制到parquet文件,然后用clickhouse查询此文件。

memory D copy ren to 'ren1e8.parquet';

:) create table rc1c2c3c4 as select c1,c2,c3,c4,sum(1)cnt from file('ren1e8.parquet') group by cube(c1,c2,c3,c4);

CREATE TABLE rc1c2c3c4
AS SELECT
c1,
c2,
c3,
c4,
sum(1) AS cnt
FROM file('ren1e8.parquet')
GROUP BY
c1,
c2,
c3,
c4
WITH CUBE

Query id: 143fa1f0b99c4daea7276944ee250bab

Ok.

572973 rows in set. Elapsed: 1.476 sec. Processed 100.00 million rows, 239.94 MB (67.75 million rows/s., 162.55 MB/s.)
Peak memory usage: 253.44 MiB.

这下返回行数和duckdb完全相同,和duckdb查询内存表的时间相比,快了0.2s。再将文件复制到clickhouse内存表。

:) create table ren as select * from file('ren1e8.parquet');

CREATE TABLE ren
AS SELECT *
FROM file('ren1e8.parquet')

Query id: 0fc6193fb75d4ef8b906d8e8f2a738a6

Ok.

100000000 rows in set. Elapsed: 5.980 sec. Processed 100.00 million rows, 277.89 MB (16.72 million rows/s., 46.47 MB/s.)
Peak memory usage: 277.83 MiB.

:) create table rc1c2c3c4m as select c1,c2,c3,c4,sum(1)cnt from ren group by cube(c1,c2,c3,c4);

CREATE TABLE rc1c2c3c4m
AS SELECT
c1,
c2,
c3,
c4,
sum(1) AS cnt
FROM ren
GROUP BY
c1,
c2,
c3,
c4
WITH CUBE

Query id: a5561df0ad59439599765ad60417bfe9

Ok.

572973 rows in set. Elapsed: 1.252 sec. Processed 100.00 million rows, 1.60 GB (79.88 million rows/s., 1.28 GB/s.)
Peak memory usage: 215.22 MiB.

结果又快了0.2秒。
补记:
我把rand()返回同一个值的问题在clickhouse存储库中提问,得到了解答(https://github.com/ClickHouse/ClickHouse/discussions/108051)。很简单,填一个不同的参数即可。

./clickhouse
ClickHouse local version 26.6.1.731 (official build).

:) create table ren as select
(rand(1)%2+1)::int c1,
(rand(2)%100+1)::int c2,
(rand(3)%30+1)::int c3,
(rand(4)%60+1)::int c4,
(rand(5)%5+1)::int c5
from generate_series(1,100000000);

CREATE TABLE ren
AS SELECT
CAST(((rand(1) % 2) + 1), 'int') AS c1,
CAST(((rand(2) % 100) + 1), 'int') AS c2,
CAST(((rand(3) % 30) + 1), 'int') AS c3,
CAST(((rand(4) % 60) + 1), 'int') AS c4,
CAST(((rand(5) % 5) + 1), 'int') AS c5
FROM generate_series(1, 100000000)

Query id: b7d52a36042a4357b2dcc49a3d277b84

Ok.

100000000 rows in set. Elapsed: 5.764 sec. Processed 100.00 million rows, 800.00 MB (17.34 million rows/s., 138.76 MB/s.)
Peak memory usage: 63.60 MiB.

:) create table rc1c2c3c4m as select c1,c2,c3,c4,sum(1)cnt from ren group by cube(c1,c2,c3,c4);

CREATE TABLE rc1c2c3c4m
AS SELECT
c1,
c2,
c3,
c4,
sum(1) AS cnt
FROM ren
GROUP BY
c1,
c2,
c3,
c4
WITH CUBE

Query id: f391c8e79a6b4cc094725451f4e48204

Ok.

572973 rows in set. Elapsed: 1.091 sec. Processed 100.00 million rows, 1.60 GB (91.64 million rows/s., 1.47 GB/s.)
Peak memory usage: 215.22 MiB.

:)

赞(0)
未经允许不得转载:171主机测评 » clickhouse 26.6和duckdb 1.6dev的group by cube查询比较
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址