男女之间做那个的网站,有没有网站是免费做店招图片的,招标网与采购网,那些免费网站可以做国外贸易查询CK手册发现#xff0c;即便对数据一致性支持最好的Mergetree#xff0c;也只是保证最终一致性#xff1a; 我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候#xff0c;会出现短暂数据不一致的情况。 在某些对一致性非常敏感的场景#xff0c;通常有… 查询CK手册发现即便对数据一致性支持最好的Mergetree也只是保证最终一致性 我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候会出现短暂数据不一致的情况。 在某些对一致性非常敏感的场景通常有以下几种解决方案。 1 准备测试表和数据 1创建表 CREATE TABLE test_a(user_id UInt64,score String,deleted UInt8 DEFAULT 0,create_time DateTime DEFAULT toDateTime(0)
)ENGINE ReplacingMergeTree(create_time)
ORDER BY user_id;其中: user_id 是数据去重更新的标识; create_time 是版本号字段每组数据中 create_time 最大的一行表示最新的数据; deleted 是自定的一个标记位比如 0 代表未删除1 代表删除数据。 2写入 1000万 测试数据 INSERT INTO TABLE test_a(user_id,score)
WITH(SELECT [A,B,C,D,E,F,G]
)AS dict
SELECT number AS user_id, dict[number%71] FROM numbers(10000000);3修改前 50万 行数据修改内容包括 name 字段和 create_time 版本号字段 INSERT INTO TABLE test_a(user_id,score,create_time)
WITH(SELECT [AA,BB,CC,DD,EE,FF,GG]
)AS dict
SELECT number AS user_id, dict[number%71], now() AS create_time FROM numbers(500000);4统计总数 SELECT COUNT() FROM test_a;10500000还未触发分区合并所以还未去重。 2 手动 OPTIMIZE 在写入数据后立刻执行OPTIMIZE强制触发新写入分区的合并动作。 OPTIMIZE TABLE test_a FINAL;语法OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID partition_id] [FINAL] [DEDUPLICATE [BY expression]]3 通过 Group by 去重 1执行去重的查询 SELECTuser_id ,argMax(score, create_time) AS score, argMax(deleted, create_time) AS deleted,max(create_time) AS ctime
FROM test_a
GROUP BY user_id
HAVING deleted 0;函数说明 argMax(field1field2):按照 field2 的最大值取 field1 的值。 当我们更新数据时会写入一行新的数据例如上面语句中通过查询最大的 create_time 得到修改后的score字段值。 2创建视图方便测试 CREATE VIEW view_test_a AS
SELECTuser_id ,argMax(score, create_time) AS score, argMax(deleted, create_time) AS deleted,max(create_time) AS ctime
FROM test_a
GROUP BY user_id
HAVING deleted 0;3插入重复数据再次查询 #再次插入一条数据
INSERT INTO TABLE test_a(user_id,score,create_time) VALUES(0,AAAA,now())#再次查询
SELECT *
FROM view_test_a
WHERE user_id 0;4删除数据测试 #再次插入一条标记为删除的数据
INSERT INTO TABLE test_a(user_id,score,deleted,create_time) VALUES(0,AAAA,1,now());#再次查询刚才那条数据看不到了
SELECT *
FROM view_test_a
WHERE user_id 0;这行数据并没有被真正的删除而是被过滤掉了。在一些合适的场景下可以结合 表级别的 TTL 最终将物理数据删除。 4 通过 FINAL 查询 在查询语句后增加FINAL修饰符这样在查询的过程中将会执行Merge的特殊逻辑例如数据去重预聚合等。 但是这种方法在早期版本基本没有人使用因为在增加 FINAL之后我们的查询将会变成一个单线程的执行过程查询速度非常慢。 在v20.5.2.7-stable版本中FINAL查询支持多线程执行并且可以通过max_final_threads 参数控制单个查询的线程数。但是目前读取part部分的动作依然是串行的。 FINAL查询最终的性能和很多因素相关列字段的大小、分区的数量等等都会影响到最终的查询时间所以还要结合实际场景取舍。 参考链接https://github.com/ClickHouse/ClickHouse/pull/10463 使用hits_v1表进行测试 分别安装了20.4.5.36 和 21.7.3.14 两个版本的ClickHouse进行对比。 4.1 老版本测试 1普通查询语句 select * from visits_v1 WHERE StartDate 2014-03-17 limit 100; 2FINAL查询 select * from visits_v1 FINAL WHERE StartDate 2014-03-17 limit 100; 先前的并行查询变成了单线程。 4.2 新版本测试 1普通语句查询 select * from visits_v1 WHERE StartDate 2014-03-17 limit 100 settings max_threads 2; 查看执行计划 explain pipeline select * from visits_v1 WHERE StartDate 2014-03-17 limit 100 settings max_threads 2; (Expression) ExpressionTransform × 2 (SettingQuotaAndLimits) (Limit) Limit 2 → 2 (ReadFromMergeTree) MergeTreeThread × 2 0 → 1 明显将由2个线程并行读取 part 查询。 2FINAL查询 select * from visits_v1 final WHERE StartDate 2014-03-17 limit 100 settings max_final_threads 2; 查询速度没有普通的查询快但是相比之前已经有了一些提升,查看 FINAL 查询的执行计划 explain pipeline select * from visits_v1 final WHERE StartDate 2014-03-17 limit 100 settings max_final_threads 2; (Expression) ExpressionTransform × 2 (SettingQuotaAndLimits) (Limit) Limit 2 → 2 (ReadFromMergeTree) ExpressionTransform × 2 CollapsingSortedTransform × 2 Copy 1 → 2 AddingSelector ExpressionTransform MergeTree 0 → 1 从CollapsingSortedTransform这一步开始已经是多线程执行但是读取 part 部分的动作还是串行。