真实建一个物化视图,验证它对创建前历史数据的真实态度(不自动回填),并说明它真实的加速原理是减少查询时要读取的数据量,而不是让计算本身变快。
代码CREATE TABLE demo.mv_source2 (k UInt64, cat UInt8, amt Float64) ENGINE=MergeTree ORDER BY k; INSERT INTO demo.mv_source2 SELECT number, number%10, number*1.5 FROM numbers(500000); -- 真实先插入50万行,这时候还没有物化视图 CREATE TABLE demo.mv_target2 (cat UInt8, total SimpleAggregateFunction(sum, Float64)) ENGINE=AggregatingMergeTree ORDER BY cat; CREATE MATERIALIZED VIEW demo.mv_view2 TO demo.mv_target2 AS SELECT cat, sum(amt) AS total FROM demo.mv_source2 GROUP BY cat; -- 真实这时候才创建物化视图
-- 物化视图刚创建完,source里明明已经有50万行了: SELECT count() FROM demo.mv_target2; → 0 ← 真实是空的,历史数据没有被自动回填 -- 真实再插入50万行新数据(第500000到999999号): INSERT INTO demo.mv_source2 SELECT number, number%10, number*1.5 FROM numbers(500000, 500000); SELECT cat, sum(total) FROM demo.mv_target2 GROUP BY cat ORDER BY cat; → 0 56249625000 1 56249700000 ... -- 这些数字真实只对应第二批50万行,不包含第一批的历史数据
直接查明细表:SELECT cat,sum(amt) FROM mv_source GROUP BY cat 真实要扫描并聚合100万行原始数据,每次查询都要重新算一遍 查预聚合表:SELECT cat,sum(total) FROM mv_target GROUP BY cat 真实只需要读10行(每个cat一行),做一次微不足道的二次求和
本文测出来两者在这个数据规模下的墙钟耗时差不多(都在几十毫秒,被client进程启动开销掩盖),但真实读取的数据量相差了10万倍(100万行 vs 10行)——物化视图真实的价值不是让"同一次计算"变快,而是把原本需要在查询时现场完成的聚合计算,提前分摊到了每次数据写入的时候:数据量越大、查询频率越高,物化视图省下来的重复计算量就越可观,本系列前面《Aggregate Function State》验证过的AggregateFunction类型也经常搭配物化视图使用,让这份"提前算好"的中间状态既能持续被新数据增量更新,又能在最终查询时快速合并出结果,而不需要每次从最原始的明细数据重新算一遍。
每一步都是本文上面用真实物化视图跑出来的原始结果。
MATERIALIZED VIEW ... TO ... AS SELECT