2017-06-06 12 views
1

我的物化视图基础表有6M记录,并且每次都进行COMPLETE刷新。 MVIEW底层查询有18个表连接(所有表在同一模式中)。它每次刷新时都会阻塞PGA内存,我会收到警告。所以我的问题在下面。Oracle:物化视图vs存储过程在重新生成时的大数据方面

1)我应该将物化视图更改为存储过程吗?存储过程将使光标具有与Mview相同的查询,并且它将一次使用BULK COLLECT和LIMIT 1000行将数据加载到新表中。我们将编写一份Autosys作业(每天一次在非工作时间)致电该程序。

下面是我改变PROC:

CREATE OR REPLACE PROCEDURE proc_reporting IS 

CURSOR cur_rows IS 
(Old MVIEW query) 

TYPE reporting_type IS TABLE OF reporting_test%ROWTYPE INDEX BY PLS_INTEGER; 
l_reporting_type reporting_type; 

BEGIN 

EXECUTE IMMEDIATE 'TRUNCATE TABLE reporting_test'; 

OPEN cur_rows; 
LOOP 
    FETCH cur_rows BULK COLLECT INTO l_reporting_type LIMIT 1000; 
    EXIT WHEN l_reporting_type.count = 0; 

      BEGIN 
      FORALL i IN l_reporting_type.FIRST .. l_reporting_type.LAST SAVE EXCEPTIONS 
      INSERT INTO reporting_test VALUES (l_reporting_type(i).column_1 .. l_reporting_type(i).column_n); 

      EXCEPTION 
      WHEN ex_dml_errors THEN 
       l_error_count := SQL%BULK_EXCEPTIONS.count; 
       DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count); 
       FOR i IN 1 .. l_error_count 
       LOOP 
       DBMS_OUTPUT.put_line('Error: ' || i || 
        ' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index || 
        ' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE)); 
       END LOOP; 
      END; 

END LOOP; 
CLOSE cur_rows; 
END; 
+0

物化视图和存储过程是两个不同的东西。你是说你会使用存储过程将数据写入表中并使用该表而不是物化视图?很显然,一张表不支持查询重写,而MV则支持。理想情况下,您应该改变您的MV以启用增量刷新。 –

+0

您是否运行[DBMS_MVIEW.EXPLAIN_MVIEW()](http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_mview.htm#CEGGEHHC)查看您是否可以调整视图以进行快速刷新? – APC

+0

Hi @ Nick.McDermaid是的,我将使用存储过程将数据写入表并使用该表而不是物化视图。我目前的MV有DISABLE QUERY REWRITE,我们也不希望QUERY REWRITE成为ENABLE。我不能将MV更改为增量刷新,因为它具有UNION查询(选择A UNION SELECT B)。 – Wasim

回答

0

我改变了MVIEW的底层查询,并将MATVIEW查询分成两部分,即两个MVIEW。我将所有的一对一关系表移到新的MVIEW中,并使其快速刷新。我们正在将新的MVIEW推向主MVIEW。通过这种方法,更少的数据被加载到PGA内存中。我们已经将新的MVIEW加载到FAST,以增强刷新模式。现在我没有得到阻止PGA内存的警告。

0

我同意你的第一个方法应该是检查MView的SQL调优。如果您拥有AWR许可证,则可以通过SQL Tuning Advisor运行它。还请指定PGA错误,可能是您的DBA需要增加pga_aggregate_target和/或pga_aggregate_limit。在很多情况下,增加PGA和/或SGA可以显着提高性能,但我总是先尝试SQL调整。

+0

MVIEW的基础查询引用了VIEW。这个VIEW基本上是表“A”和“A_HISTORY”表的连接。这两张表是交易表,数据在3.8M(A)和22.3M(A_HISTORY)左右。除此之外,它再次将这个VIEW加入另外15个表格,包括A_HISTORY。它导致会话PGA内存超出警戒。我将VIEW更改为MVIEW,并修改了主MVIEW以引用MVIEW。通过这种方法,事务表连接数据将在物理表(MVIEW)中并且数据将会更少。请检阅我的方法并提供宝贵的意见。 – Wasim

+0

任何减少解决查询所需的I/O和CPU资源的方法都可行。根据我的经验,有时值得回到查询的原始需求并理解数据模型,查看是否有更好/更简单的方法来满足要求,因为原始应用程序视图通常是针对不同要求的设置以及它们在新要求中的使用可能变得繁琐。关于您的方法的进一步说明:视图Mview介绍了刷新的复杂性,并且您可能需要在新的Mview上使用索引。 –

+0

调整的基本原则:在尽可能快的过程中对非常大的表进行子集划分。毫无疑问,您很熟悉“解释计划”(显示Oracle优化器将采用的执行路径)和其他调整工具[如果不是,那么您可能需要]。 –