如何给ClickHouse表生成随机真实测试数据

本文介绍了如何使用ClickHouse的generateRandom函数来创建测试数据,包括其语法、参数以及不同类型的随机分布,如均匀分布、正太分布和指数分布。这些功能有助于模拟真实业务场景并进行性能测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习ClickHouse数据库,通常需要下载官网一些示例数据。我们也可以通过内置函数generateRandom快速生成测试数据,从而测试学习一些特性的性能及底层原理。

函数语法

generateRandom函数基于给定schema生成随机数据,用于填充测试表。不是所有类型都支持。

generateRandom('name TypeName[, name TypeName]...', [, 'random_seed'[, 'max_string_length'[, 'max_array_length']]])
  • name — 列名称.
  • TypeName — 列类型.
  • max_array_length — 所有生成arrays或maps最大元素,默认为10.
  • max_string_length — 生成字符串的最大长度,默认为10.
  • random_seed — 手动指定随机种子,为null则随机生成.

返回与schema对应的表对象。

举例:

SELECT * FROM generateRandom('a Array(Int8), d Decimal32(4), c Tuple(DateTime64(3), UUID)', 1, 10, 2) LIMIT 3;

上面示例生成三个字段schema数据,可选参数中第一个是随机种子,第二个最大字符串长度,第三个最大数组长度,执行SQL返回结果:

┌─a────────┬────────────d─┬─c──────────────────────────────────────────────────────────────────┐
│ [77]     │ -124167.6723 │ ('2061-04-17 21:59:44.573','3f72f405-ec3e-13c8-44ca-66ef335f7835') │
│ [32,110] │ -141397.7312 │ ('1979-02-09 03:43:48.526','982486d1-5a5d-a308-e525-7bd8b80ffa73') │
│ [68]     │  -67417.0770 │ ('2080-03-12 14:17:31.269','110425e5-413f-10a6-05ba-fa6b3e929f15') │
└──────────┴──────────────┴────────────────────────────────────────────────────────────────────┘

也可以先创建表,然后插入随机生成数据:

CREATE TABLE random (a Array(Int8), d Decimal32(4), c Tuple(DateTime64(3), UUID)) engine=Memory;
INSERT INTO random SELECT * FROM generateRandom() LIMIT 2;
SELECT * FROM random;

返回结果:

┌─a────────────────────────────┬────────────d─┬─c──────────────────────────────────────────────────────────────────┐
│ []                           │   68091.8197 │ ('2037-10-02 12:44:23.368','039ecab7-81c2-45ee-208c-844e5c6c5652') │
│ [8,-83,0,-22,65,9,-30,28,64] │ -186233.4909 │ ('2062-01-11 00:06:04.124','69563ea1-5ad1-f870-16d8-67061da0df25') │
└──────────────────────────────┴──────────────┴────────────────────────────────────────────────────────────────────┘

生成压力测试数据

SELECT * FROM generateRandom('a UUID, b DateTime, c Text', NULL, 2048) LIMIT 1000;

这里保持随机种子为null,字符串长度为2048,即最大长度。

下面示例利用测试数据进行压力测试,生成1亿数据量:

INSERT INTO test_stress
SELECT * FROM generateRandom('ID Int64, test_until_2k Text',1,2048) LIMIT 100000000;

随机数据分布

均匀分布

均匀分布默认数据范围为[0,1), 也可以通过参数指定数据范围:

SELECT randUniform(5,10)

如果需要整数,可以使用下面语句,生成[5,9]返回的整数:

SELECT floor(randUniform(5, 10)) AS r

非均匀分布

首先最常用的应该是正太分布:

SELECT randNormal(100, 5) -- 100 为均值,5是标准差

示例:

SELECT
    floor(randNormal(100, 5)) AS k,
    count(*) AS c,
    bar(c, 0, 50000, 100)
FROM numbers(100000) GROUP BY k ORDER BY k ASC

在这里插入图片描述

除了正太分布,还有伯努利分布、二项分布、对数分布、指数分布、卡方分布、T分布、F分布、泊松分布等。

下面是指数分布的示例,用户消费记录符合指数分布:

CREATE TABLE purchases
(
    `dt` DateTime,
    `customer_id` UInt32,
    `total_spent` Float32
)
ENGINE = MergeTree
ORDER BY dt
INSERT INTO purchases SELECT
    now() - randUniform(1, 1000000.),
    number,
    15 + round(randExponential(1 / 10), 2)
FROM numbers(1000000)

这里使用序号作为用户ID,采用均分分布随机数往前推移时间用于分散日期。消费金额采用指数分布,15是最低值。

最后进行验证:

SELECT
    floor(total_spent) AS s,
    count(*) AS n,
    bar(n, 0, 350000, 50)
FROM purchases
GROUP BY s
ORDER BY s ASC

生成图示如下:

在这里插入图片描述

总结

本文介绍了生成随机测试的函数,包括基本语法及一些数据分布函数的应用,这些函数需至少22.10版本。利用这些函数让数据更真实、更贴近实际业务场景。参考资料:https://clickhouse.com/blog/generating-random-test-distribution-data-for-clickhouse

官方文档:https://clickhouse.com/docs/en/sql-reference/functions/random-functions#randuniform

### ClickHouse基准测试方法与工具 #### 使用Yandex官方推荐的Benchmark Tools 为了评估ClickHouse的读写性能,可以采用多种方式。一种常用的方法是利用由Yandex开发并维护的一系列专门针对ClickHouse设计的压力测试工具[^1]。 这些工具能够模拟大量并发查询请求来检验系统的响应速度以及吞吐量现。通过调整参数配置(如线程数、大小),可以获得不同负载条件下的详尽性能指标报告。 #### 利用第三方在线服务——Load Impact 除了专用软件外,还可以借助像Load Impact这样的云端负载测试平台来进行更全面深入地考察。该类服务平台允许用户创建复杂的场景设定,并支持跨多个地理位置发起攻击流量,从而真实反映实际生产环境中可能遇到的各种情况。 对于具体的实现细节而言: - **准备阶段** 需要先准备好待测的数据集,确保它们代了典型的应用案例;同时也要注意清理历史记录以免干扰新实验的结果准确性。 - **编写脚本** 根据业务逻辑定制相应的SQL语句或者API调用来构建工作流模型。这一步骤至关重要因为它直接影响到最后所得结论的有效性和可靠性。 - **执行测试** 启动预先编写的程序去触发一系列连续不断的访问动作直至达到预期次数为止。期间密切监控资源消耗状况以便及时发现潜在瓶颈所在之处。 - **分析结果** 测试完成后导出日志文件用于后续统计处理。重点关注平均延迟时间、最大/最小值分布范围等核心统计数据项,以此作为优化改进措施的重要依据之一。 ```sql -- 创建示例格结构 CREATE TABLE IF NOT EXISTS example_table ( id UInt32, timestamp DateTime, value Float64 ) ENGINE = MergeTree() ORDER BY (id); -- 插入随机生成的数据样本 INSERT INTO example_table SELECT number AS id, now() - interval number minute AS timestamp , rand()/1000 FROM numbers(1e7); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值