经常刷新Oracle中的物化视图

时间:2016-09-16 10:28:48

标签: oracle query-optimization materialized-views

我们正在优化性能,并希望创建基于少数几个表的连接构建的物化视图(数百万条记录)。此视图将用于在文件夹中显示用户文档,延迟时间不超过几(3-5)秒。

我认为它必须是具有几秒刷新间隔的不合适的MV。

从数据库的角度来看是否可以接受解决方案?

视图将是这样的:

38,89

更新 瓶颈在于:

12,89

计划是:

计划哈希值:3579815467

 SELECT *
   FROM documents this_
        LEFT OUTER JOIN account_statements this_1_
           ON this_.Id = this_1_.FK_Document
        LEFT OUTER JOIN contracts this_2_ ON this_.Id = this_2_.FK_Document
        LEFT OUTER JOIN pension_agreements this_3_
           ON this_.Id = this_3_.FK_Contract
        LEFT OUTER JOIN dead this_4_ ON this_.Id = this_4_.FK_Document
        LEFT OUTER JOIN pay_orders this_5_ ON this_.Id = this_5_.FK_Document
        LEFT OUTER JOIN pay_registers this_6_
           ON this_.Id = this_6_.FK_Document
        LEFT OUTER JOIN pocards this_7_ ON this_.Id = this_7_.FK_Document
        LEFT OUTER JOIN ransom_agreements this_8_
           ON this_.Id = this_8_.FK_Document
        LEFT OUTER JOIN successor_statements this_9_
           ON this_.Id = this_9_.FK_Document
        INNER JOIN document_treenodes treenodes14_
           ON this_.Id = treenodes14_.fk_document
        INNER JOIN treenodes treenode2_
           ON treenodes14_.fk_treenode = treenode2_.Id
        LEFT OUTER JOIN registration_cards regcard1_
           ON this_.fk_registration_card = regcard1_.Id
        LEFT OUTER JOIN employees todirectem12_
           ON regcard1_.to_direct = todirectem12_.Id
        LEFT OUTER JOIN REG_CARD_STATUSES regcardsta11_
           ON regcard1_.status = regcardsta11_.Id
        LEFT OUTER JOIN filestorages filestorag10_
           ON this_.fk_file = filestorag10_.Id
        LEFT OUTER JOIN actions holdaction4_
           ON this_.fk_hold = holdaction4_.Id
        LEFT OUTER JOIN employees holdemploy5_
           ON holdaction4_.fk_operator = holdemploy5_.Id
        LEFT OUTER JOIN actions doneaction6_
           ON this_.fk_done = doneaction6_.Id
        LEFT OUTER JOIN employees doneemploy7_
           ON doneaction6_.fk_operator = doneemploy7_.Id
        LEFT OUTER JOIN actions signaction8_
           ON this_.fk_signed = signaction8_.Id
        LEFT OUTER JOIN employees signemploy9_
           ON signaction8_.fk_operator = signemploy9_.Id
        LEFT OUTER JOIN actions scanaction3_
           ON this_.fk_scan = scanaction3_.Id

1 个答案:

答案 0 :(得分:0)

我冒昧地“重新格式化”你的查询(顺便说一句:我认为那里有一些复制粘贴错误,有些部分看起来接近结尾)

'布局'对实际执行时间没有任何影响,但它让让我更容易理解你在做什么(仅仅因为我习惯了自己的风格,我并没有声称它更好,它只是习惯了)

无论如何,如果我理解正确并且没有弄乱括号,那么这应该等同于你的查询:

SELECT *
  FROM documents this_
 INNER JOIN document_treenodes treenodes14_ 
         ON treenodes14_.fk_document = this_.Id
 INNER JOIN treenodes treenode2_ 
         ON treenode2_.Id = treenodes14_.fk_treenode
        AND treenode2_.Id = 1235 /* :p3 */ 
  LEFT OUTER JOIN registration_cards regcard1_ 
               ON regcard1_.Id = this_.fk_registration_card 

 WHERE this_.fk_deleted IS NULL 
   AND this_.fk_done IS NULL 
   AND ( 
          this_.isdelete IS NULL OR this_.isdelete = 0 /* :p2 */
       )
   AND ( 
          regcard1_.status IS NULL OR regcard1_.status NOT IN (3 /* :p0 */, 4 /* :p1 */, 1 /* :p4 */) 
       )

 ORDER BY this_.Id DESC
OFFSET 0 ROWS
 FETCH FIRST 50 /* :p5 */ ROWS ONLY

我怀疑这种变化会带来很大的不同,但它可能会改变系统接近步骤8的方式。目前的计划中有9个。值得一试=)

无论如何,我从查询中“学到的”是你似乎想要所有没有匹配[registration_cards]记录的记录,但如果有,那么它们不应该具有状态3,4或1(:p0, :分别为p1,:p4)。 =>这不等于说你想要没有匹配[registration_cards]记录的状态为3,4或1的所有[文件]记录吗?

SELECT *
  FROM documents this_
 INNER JOIN document_treenodes treenodes14_ 
         ON treenodes14_.fk_document = this_.Id
 INNER JOIN treenodes treenode2_ 
         ON treenode2_.Id = treenodes14_.fk_treenode
        AND treenode2_.Id = 1235 /* :p3 */ 

 WHERE this_.fk_deleted IS NULL 
   AND this_.fk_done IS NULL 
   AND ( 
         this_.isdelete IS NULL OR this_.isdelete = 0 /* :p2 */
       )
   AND NOT EXISTS ( SELECT *
                      FROM registration_cards regcard1_ 
                     WHERE regcard1_.Id = this_.fk_registration_card 
                       AND regcard1_.status IN (3 /* :p0 */, 4 /* :p1 */, 1 /* :p4 */) )

 ORDER BY this_.Id DESC
OFFSET 0 ROWS
 FETCH FIRST 50 /* :p5 */ ROWS ONLY

假设[registration_card] .Id是表的PK,或者在状态和Id字段上有覆盖索引,这可能会稍快一些。就像我之前说过的那样,我的印象是大多数时候在排序结果集时丢失了但是我可能会完全误解解释计划。谷歌搜索实际上似乎告诉我the explain plan is but guesswork and not 'the real deal' ....叹息,有时我真的很同情你可怜的Oracle用户= P