我有一个基本交易表。然后,我有大约15个中间步骤,其中我将合并维表,执行一些聚合并实现业务逻辑。我目前的处理方式是为中间阶段创建临时表,然后将这15个步骤发布到物理表中,以填充最终结果。它是一种更好的方法,或者使用实例化视图代替这些中间临时表是一种更好的方法。如果将物化视图用于中间步骤是更好的方法,那么请让我知道为什么吗?
已经尝试编写两种方法的脚本,将15个中间步骤编写为全局临时表和实体化视图。与临时表相比,我发现MV的性能略有提高,但这是以过多的物理存储为代价的。不确定哪个是最佳做法,为什么?
答案 0 :(得分:1)
根据您所说的,我想说(使用全局或私有的,取决于您使用的数据库版本)临时表是一个更好的选择。为什么?因为您正在“计算”某物,所以将这些计算的结果存储到某些表中,然后将其重新用于其他处理。所有这些-如果没有临时表是无法完成的,那么所有这些都将由表完成。
顾名思义,材料化视图是 view 。这是某些查询的结果,但是-与“普通”视图相反,它实际上占用了空间。可以刷新(根据需要,在更改源数据时或根据计划)。是的,它有它的优点,尽管我目前看不到您正在做的任何事情。
答案 1 :(得分:1)
临时表写入磁盘,因此读取和写入都会产生I / O成本。同样,大多数站点也无法正确管理其临时表,它们最终会在默认的临时表空间上使用,默认的临时表空间是每个人用于排序等的TEMP表空间。因此,那里存在资源争用的可能性。
材料化视图旨在实现我们数据集的各个方面,这些方面通常被许多不同的查询重用。这就是为什么最常见的用例是存储低级数据的高级聚合。这听起来不像这里的用例。还有!
我正在完全刷新MV,而不是增量刷新
所以不。
然后我有大约15个中间步骤,其中我将合并维表,执行一些聚合并实现业务逻辑。
这是查询数据的一种非常程序化的方式。有时无法避免这种情况,尤其是在某些数据仓库场景中。但是,并不能因此而需要具体化那些查询的输出。另一种方法是使用WITH子句。一个WITH子查询的输出可以输入到较低的子查询中。
with sq1 as (
select whatever
, count(*) as t1_tot
from t1
group by whatever
) , sq2 as (
select sq1.whatever
, max(t2.blah) as max_blah
from sq1
join t2 on t2.whatever = sq1.whatever
) , sq3 as (
select sq2.whatever
,(t3.meh + t3.huh) as qty
from sq2
join t3 on t3.whatever = sq2.whatever
where t3.something >= sq2.max_blah
)
select sq1.whatever
,sq1.t1_tot
,sq2.max_blah
,sq3.qty
from sq1
join sq2 on sq2.whatever = sq1.whatever
join sq3 on sq3.whatever = sq1.whatever
不是说这不是一个可怕的查询,这是部门的恐怖。但是它的性能可能比您的MViews和GTT好。 (Oracle可以选择具体化那些中间结果集,但we can use hints to affect that。)
您甚至可以从采用这种方法的过程中发现,某些步骤是不必要的,并且可以将多个步骤组合到一个查询中。当然,在现实生活中,我会将上面的玩具声明写为一个查询,而不是三个子查询的连接。