[fix](mv) Avoid unioning query-unused MV partitions#63081
[fix](mv) Avoid unioning query-unused MV partitions#63081foxtail463 wants to merge 1 commit intoapache:masterfrom
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
fce5497 to
8b8e561
Compare
问题在 MV union rewrite 过程中, 旧逻辑会把所有需要从 MV scan 中移除的分区都映射回 base table 分区,并加入 这样可能会生成不必要的 base table 示例假设有一张按日期分区的 base table: 原始查询只需要读取 3 个 base table 分区: 但是在 MV union rewrite 过程中,临时生成的 MV scan 可能会选择一个更大的分区范围: 假设当前有效的 MV 分区只有查询真正需要的这几个: 那么需要从 MV scan 中移除的分区是: 这些被移除的 MV 分区都不在原始查询范围内。 它们应该从 MV scan 中移除,但不应该再从 base table 中 union 回来,因为原始查询根本不需要这些分区。 这个 PR 之前旧逻辑会把所有映射出来的 base table 分区都加入 baseTableNeedUnionPartitionNameSet.addAll(baseTablePartitions);因此最终改写出来的计划可能逻辑上类似于: SELECT ...
FROM mv_sales_daily
WHERE dt IN ('2026-04-01', '2026-04-02', '2026-04-03')
UNION ALL
SELECT ...
FROM sales
WHERE dt IN (
'2026-03-01', ..., '2026-03-31',
'2026-04-04', ..., '2026-04-28'
);第二个 这会带来两个问题:
这个 PR 之后这个 PR 会先取交集,只把原始查询真正用到的 base table 分区加入 baseTableNeedUnionPartitionNameSet.addAll(
Sets.intersection(baseTablePartitions, queryUsedBaseTablePartitionNameSet));在上面的例子中: 所以不会生成任何不必要的 base table union 分支。 最终改写计划只需要: SELECT ...
FROM mv_sales_daily
WHERE dt IN ('2026-04-01', '2026-04-02', '2026-04-03'); |
|
run buildall |
TPC-H: Total hot run time: 29739 ms |
TPC-DS: Total hot run time: 171885 ms |
FE UT Coverage ReportIncrement line coverage |
Problem Summary:
In MV union rewrite, rewrittenPlanUsePartitionNameSet may contain extra MV partitions outside the query range. For example, the query only uses {p20260401, p20260402, p20260403}, but the rewritten MV scan may select partitions from p20260301 to p20260428. The old compensation logic mapped all removed MV partitions back to base table partitions and added them into baseTableNeedUnionPartitionNameSet. This created unnecessary base table union branches, increased the MV candidate cost, and could make explain show MaterializedViewRewriteSuccessButNotChose.