0

我有一个维度模型,其中包含一个按日期进行范围分区的大型事实表(数百万行)和未分区的较小维度表。我遇到了物化视图,它经常在这些场景中用于提高查询性能。

现在,我想知道以下两种方式中哪种方式更好利用这些物化视图来获取聚合报告。

A. 通过将整个事实表与所需的每个维度表连接起来,创建一个。

create materialized view my_mview execute immediate query rewrite
    select 
       fact.col1, dim1.col2, dim2.col3, sum(fact.col4)
    from 
       my_fact fact 
    inner join
      my_dim1 dim1
       on fact.dim1_key = dim1.dim1_key
    inner join 
      my_dim2 dim2
       on fact.dim2_key = dim2.dim2_key group by fact.col1, dim1.col2, dim2.col3

这似乎是使用它们的最基本方式。但这似乎相当有限,我需要为我想要创建的每个查询变体创建一个新的物化视图。

B. 在事实表的聚合上创建它,并在执行维度连接时利用查询重写。

create materialized view my_mview execute immediate query rewrite
    select 
       col1, dim1.dim2_key, dim2.dim_key, sum(fact.col4)
    from 
       my_fact fact 

并在案例 A 中执行上述连接,这将使用此聚合的物化视图进行连接,而不是整个事实表。

谁能告诉我什么时候会使用每个案例?

4

1 回答 1

0

您的第一个示例完全按照您的描述工作。

对于第二个示例,查询应该是:

create materialized view my_mview execute immediate query rewrite
    select 
       col1, fact.dim2_key, fact.dim_key, sum(fact.col4)
    from 
       my_fact fact
    group by
       col1, fact.dim2_key, fact.dim_key

这将自动加速聚合,例如

select sum(fact.col4) 
  from fact

select fact.dim_key,sum(fact.col4) 
  from fact
  group by fact.dim_key

select fact.dim2_key,sum(fact.col4) 
  from fact
  group by fact.dim2_key

我认为 Oracle 不会自动将您的第一种类型的查询重写为此 MV,因为在 MV 中,连接列已经分组(它们也应该在您的第二个示例中分组)。它从来没有发生在我们身上。然而,这也可能取决于 dim 和事实表之间是否定义了关系以及 QUERY_REWRITE_INTEGRITY 参数的值,因此这里仍有一些测试空间。

您仍然可以通过以特定方式编写查询来获得性能提升

WITH preaggr as (
    select 
       col1, fact.dim2_key, fact.dim_key, sum(fact.col4)
    from 
       my_fact fact
    group by
       col1, fact.dim2_key, fact.dim_key
)

select
  dim2.col1,
  sum(preaggr.col4)
from
  preaggr
join
  dim2
on
  preaggr.dim2_key = fact.dim2_key
group by  
  dim2.col1
于 2015-01-11T09:14:19.313 回答