ClickHouse没想象中好用!除非避开了这12个坑……
引言
在ClickHouse,我们始终在思考我们的入门体验以及如何帮助用户在尽可能短的时间内从我们的产品中获得价值。虽然大多数用户都有一个流畅的上手经验,但我们意识到ClickHouse是一个复杂的软件,并且引入了很多新的概念。加上大规模管理ClickHouse的挑战,这也是我们开发serverless ClickHouse解决方案的原因之一,它能自动处理许多常见的入门问题和后续扩展方面的挑战。
然而,有些问题仅仅是由于配置错误或更常见的是对ClickHouse行为和功能的误解。在这篇文章中,我们突出了新手用户遇到的最常见的12个问题,这些问题是由于在使用ClickHouse的过程中,不遵循最佳实践,甚至反最佳实践而导致的。对于每一个问题,我们都推荐了一个解决方案或正确的使用方法。
一、Too many parts
二、过早地进行水平扩展
三、mutation之痛
四、不必要地使用复杂类型
插入时的增加成本,因为需要动态创建列 没有使用最优的类型,比如不必要的使用Nullable 无法在主键中使用JSON列
五、插入时的去重
CREATE TABLE temp(`timestamp` DateTime,`value` UInt64)ENGINE = MergeTreeORDER BY tuple()INSERT INTO temp VALUES ('2022-10-21', 10), ('2022-10-22', 20), ('2022-10-23', 15), ('2022-10-24', 18)INSERT INTO temp VALUES ('2022-10-21', 10), ('2022-10-22', 20), ('2022-10-23', 15), ('2022-10-24', 18)clickhouse-cloud :) SELECT * FROM tempSELECT *FROM temp┌───────────timestamp─┬─value─┐│ 2022-10-21 00:00:00 │ 10 ││ 2022-10-22 00:00:00 │ 20 ││ 2022-10-23 00:00:00 │ 15 ││ 2022-10-24 00:00:00 │ 18 │└─────────────────────┴───────┘
六、选择不当的主键
七、过度使用跳数索引
八、LIMIT并不总是立即停止 + 点查
clickhouse-cloud :) SELECTpostcode1, postcode2,formatReadableQuantity(avg(price)) AS avg_priceFROM uk_price_paidGROUP BY postcode1, postcode2LIMIT 1;┌─postcode1─┬─postcode2─┬─avg_price───────┐│ AL4 │ 0DE │ 335.39 thousand │└───────────┴───────────┴─────────────────┘Elapsed: 3.028 sec, read 27.55 million rows, 209.01 MB.
clickhouse-cloud :) SELECTpostcode1, postcode2,formatReadableQuantity(avg(price)) AS avg_priceFROM uk_price_paidGROUP BY postcode1, postcode2LIMIT 1SETTINGS optimize_aggregation_in_order = 1;┌─postcode1─┬─postcode2─┬─avg_price───────┐│ AL4 │ 0DE │ 335.39 thousand │└───────────┴───────────┴─────────────────┘Elapsed: 0.999 sec, read 4.81 million rows, 36.48 MB.
九、Readonly tables
十、查询内存限制超出
十一、关于物化视图的问题
我们经常看到用户对物化视图的工作方式存在误解。物化视图对源表数据一无所知,实际上只是在插入时的触发器 - 只能在插入的数据块上运行。它们无法看到合并、分区删除或mutation。如果用户更改了源表,他们因此也必须更新关联的物化视图 - 目前没有办法能保持它们同步。 用户在单个表上添加了太多的物化视图。这些视图并不是没有消耗的,并且必须在每次插入时运行。一个表上超过50个物化视图通常是过多的,会降低插入速度。除了计算开销外,每个物化视图都会从其运行的块创建一个新的part - 可能引发前面讨论的“Too many Parts”问题。请注意,通过设置 parallel_view_processing 来并行运行视图,可以提高性能。 状态函数是ClickHouse的一个引人注目的功能,允许数据在后续的查询中使用聚合函数进行总结。具有许多这些函数的物化视图,尤其是计算分位数状态函数的那些物化视图,可能对CPU开销很大并导致插入变慢。
CREATE MATERIALIZED VIEW test.basicENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate)AS SELECTCounterID,StartDate,sumState(Sign) AS Visits,uniqState(UserID) AS UsersFROM test.visitsGROUP BY CounterID, StartDate;
CREATE MATERIALIZED VIEW test.summing_basicENGINE = SummingMergeTreePARTITION BY toYYYYMM(d)ORDER BY (CounterID, StartDate)AS SELECT CounterID, StartDate, count() AS cntFROM sourceGROUP BY CounterID, StartDate;
CREATE MATERIALIZED VIEWtest.mv1 (timestamp Date, id Int64, counter Int64)ENGINE = SummingMergeTreeORDER BY (timestamp, id)ASSELECT timestamp, id, count() as counterFROM sourceGROUP BY timestamp, id;十二、生产环境中的实验性功能
结论