@@ -981,6 +981,108 @@ group by
981981 l_suppkey;
982982` ` `
983983
984+ # ## 窗口函数改写
985+ 当查询和物化视图都包含窗口函数时,如果窗口函数的定义完全匹配,可以进行透明改写。
986+ 窗口函数改写能够复用物化视图中预计算的窗口函数结果,显著提升包含复杂窗口计算的查询性能。
987+ 目前支持所有窗口函数的透明改写。
988+
989+
990+ ` ` ` sql
991+ CREATE MATERIALIZED VIEW mv11_0
992+ BUILD IMMEDIATE REFRESH AUTO ON MANUAL
993+ DISTRIBUTED BY RANDOM BUCKETS 2
994+ as
995+ select *
996+ from (
997+ select
998+ o_orderkey,
999+ FIRST_VALUE(o_custkey) OVER (
1000+ PARTITION BY o_orderdate
1001+ ORDER BY o_totalprice NULLS LAST
1002+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1003+ ) AS first_value,
1004+ RANK() OVER (
1005+ PARTITION BY o_orderdate, o_orderstatus
1006+ ORDER BY o_totalprice NULLS LAST
1007+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1008+ ) AS rank_value
1009+ from
1010+ orders
1011+ ) t
1012+ where o_orderkey > 1;
1013+ ` ` `
1014+
1015+
1016+ 如下查询可以命中 mv11_0 的物化视图,节省了窗口函数的计算,可以看到查询中的条件 ` o_orderkey > 2` 和物化视图不一致,也可以改写成功
1017+ ` ` ` sql
1018+ select *
1019+ from (
1020+ select
1021+ o_orderkey,
1022+ FIRST_VALUE(o_custkey) OVER (
1023+ PARTITION BY o_orderdate
1024+ ORDER BY o_totalprice NULLS LAST
1025+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1026+ ) AS first_value,
1027+ RANK() OVER (
1028+ PARTITION BY o_orderdate, o_orderstatus
1029+ ORDER BY o_totalprice NULLS LAST
1030+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1031+ ) AS rank_value
1032+ from
1033+ orders
1034+ ) t
1035+ where o_orderkey > 2;
1036+ ` ` `
1037+
1038+
1039+ ` ` ` sql
1040+ CREATE MATERIALIZED VIEW mv11_1
1041+ BUILD IMMEDIATE REFRESH AUTO ON MANUAL
1042+ DISTRIBUTED BY RANDOM BUCKETS 2
1043+ as
1044+ select
1045+ o_orderkey,
1046+ o_orderdate,
1047+ FIRST_VALUE(o_custkey) OVER (
1048+ PARTITION BY o_orderdate
1049+ ORDER BY o_totalprice NULLS LAST
1050+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1051+ ) AS first_value,
1052+ RANK() OVER (
1053+ PARTITION BY o_orderdate, o_orderstatus
1054+ ORDER BY o_totalprice NULLS LAST
1055+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1056+ ) AS rank_value
1057+ from
1058+ orders
1059+ where o_orderdate > '2023-12-09';
1060+ ` ` `
1061+
1062+ 如下查询可以命中 ` mv11_1` 的物化视图,节省了窗口函数的计算,可以看到查询中的条件 ` o_orderdate > '2023-12-10'` 和物化视图定义不一致。
1063+ ` o_orderdate` 属于窗口函数的 partition by 字段,这种情况下,虽然查询条件 ` o_orderdate > '2023-12-10'` 早于
1064+ window 函数执行,也可以进行透明改写。
1065+
1066+
1067+ ` ` ` sql
1068+ select
1069+ o_orderdate,
1070+ FIRST_VALUE(o_custkey) OVER (
1071+ PARTITION BY o_orderdate
1072+ ORDER BY o_totalprice NULLS LAST
1073+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1074+ ) AS first_value,
1075+ RANK() OVER (
1076+ PARTITION BY o_orderdate, o_orderstatus
1077+ ORDER BY o_totalprice NULLS LAST
1078+ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1079+ ) AS rank_value
1080+ from
1081+ orders
1082+ where o_orderdate > '2023-12-10';
1083+ ` ` `
1084+ 用例中使用的是单表,多表 join 场景下,窗口函数改写同样适用。
1085+
9841086
9851087# ## Limit 和 TopN 改写
9861088当查询包含 ORDER BY 或 LIMIT 子句,或者两者都有(即 Top- N 查询)时,如果物化视图能够提供足够的数据来满足查询的 ORDER BY 和 LIMIT 要求,
0 commit comments