美文网首页互联网科技iOS开发程序员
oracle学习笔记9: model子句(下)

oracle学习笔记9: model子句(下)

作者: 猫猫_tomluo | 来源:发表于2016-08-31 06:35 被阅读153次

物化视图

--物化视图与查询重写
DROP MATERIALIZED VIEW mv_model_inventory;
CREATE MATERIALIZED VIEW mv_model_inventory
ENABLE QUERY REWRITE AS 
  select product,country, year,week,inventory,sale,receipts
  from sales_fact
  model return updated rows
  partition by(product, country)
  dimension by(year, week)
  measures(0 inventory, sale,receipts)
  rules sequential order(
   inventory[year,week] order by year, week=nvl(inventory[cv(year),cv(week)-1],0)-sale[cv(year),cv(week)]+receipts[cv(year),cv(week)]
  )
/

SELECT * FROM (
 select product,country, year,week,inventory,sale,receipts
  from sales_fact
  model return updated rows
  partition by(product, country)
  dimension by(year, week)
  measures(0 inventory, sale,receipts)
  rules sequential order(
     inventory[year,week] order by year, week=nvl(inventory[cv(year),cv(week)-1],0)-sale[cv(year),cv(week)]+receipts[cv(year),cv(week)]
  )
)
WHERE country IN ('Australia') AND product='Xtend Memory'
ORDER BY product,country,year,week;

执行计划
----------------------------------------------------------
Plan hash value: 2344724570

----------------------------------------------------------------------------------------------------

| Id  | Operation                     | Name               | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT              |                    |    96 | 10944 |   278   (2)| 00:00:04 |

|   1 |  SORT ORDER BY                |                    |    96 | 10944 |   278   (2)| 00:00:04 |

|*  2 |   MAT_VIEW REWRITE ACCESS FULL| MV_MODEL_INVENTORY |    96 | 10944 |   277   (2)| 00:00:04 |

----------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("MV_MODEL_INVENTORY"."COUNTRY"='Australia' AND
              "MV_MODEL_INVENTORY"."PRODUCT"='Xtend Memory')

并行

基于model的sql语句可以与oracle的并行执行能力无缝结合。并行和基于model的sql语句可以改善分区表的查询性能。

SELECT /*+ parallel ( sf 4) */  
  product,country, year,week,inventory,sale,receipts
  from sales_fact 
  WHERE country IN ('Australia') AND product='Xtend Memory'
  model return updated rows
  partition by(product, country)
  dimension by(year, week)
  measures(0 inventory, sale,receipts)
  rules automatic order(
     inventory[year,week] order by year, week=nvl(inventory[cv(year),cv(week)-1],0)-sale[cv(year),cv(week)]+receipts[cv(year),cv(week)]
  )

model子句执行中的分区

分区表可以改进model sql语句的性能。如果model sql中的分区列与表的分区键相匹配,分区就是被剪裁过的。分区裁剪是一门将扫描限制在较少分区中的性能优化技术。

--分区剪裁
SELECT *
  FROM (SELECT product, country, YEAR, week, inventory, sale, receipts
          FROM sales_fact sf 
          model RETURN updated rows 
          PARTITION BY(YEAR, country) 
          dimension BY(product, week) 
          measures(0 inventory, sale, receipts) 
          rules AUTOMATIC ORDER(
          inventory [ product, week ] ORDER BY product, week =
                  nvl(inventory [ cv(product), cv(week) - 1 ], 0) - sale [ cv(product),
                  cv(week) ] + +receipts [ cv(product),
                  cv(week) ]))
 WHERE YEAR = 2000
   AND country = 'Australia'
   AND product = 'Xtend Memory'

--不进行分区剪裁
SELECT * FROM (
       SELECT product, country, year, week, inventory, sale, receipts
          FROM sales_fact sf 
          model RETURN updated rows 
          PARTITION BY(product, country) 
          dimension BY(year, week) 
          measures(0 inventory, sale, receipts) 
          rules AUTOMATIC ORDER(
          inventory [ year, week ] ORDER BY year, week =
                  nvl(inventory [ cv(year), cv(week) - 1 ], 0)
                   - sale [ cv(year), cv(week) ] 
                   +receipts [ cv(year),cv(week) ]))
 WHERE YEAR = 2000
   AND country = 'Australia'
   AND product = 'Xtend Memory'


执行计划
----------------------------------------------------------
Plan hash value: 463616151

----------------------------------------------------------------------------------

| Id  | Operation           | Name       | Rows  | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------------

|   0 | SELECT STATEMENT    |            |   154 | 17556 |   310   (1)| 00:00:04 |

|*  1 |  VIEW               |            |   154 | 17556 |   310   (1)| 00:00:04 |

|   2 |   SQL MODEL ACYCLIC |            |   154 |  8624 |            | |

|*  3 |    TABLE ACCESS FULL| SALES_FACT |   154 |  8624 |   310   (1)| 00:00:04 |

----------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("YEAR"=2000)
   3 - filter("PRODUCT"='Xtend Memory' AND "COUNTRY"='Australia')

product列和country列作为分区列,但表使用year列作为分区键,执行计划中的第1步表明为证year=2000由于规则可能访问其它分区而没有推进到视图中,因为year是一个维度列。因为分区键没有前推进视图中,就不允许进行分区剪裁,从而需要扫描所有分区。

索引

选择索引来提高使用model子句的sql语句性能与选择索引提高其它的任何sql语句的性能都是一样的。可以使用访问和筛选谓语确定最佳的索引策略。

--记住sql数据访问索引
SELECT * FROM (
       SELECT product, country, year, week, inventory, sale, receipts
          FROM sales_fact sf 
          model RETURN updated rows 
          PARTITION BY(product, country) 
          dimension BY(year, week) 
          measures(0 inventory, sale, receipts) 
          rules AUTOMATIC ORDER(
          inventory [ year, week ] ORDER BY year, week =
                  nvl(inventory [ cv(year), cv(week) - 1 ], 0)
                   - sale [ cv(year), cv(week) ] 
                   +receipts [ cv(year),cv(week) ]))
 WHERE YEAR = 2000  AND country = 'Australia' AND product = 'Xtend Memory'

执行计划
----------------------------------------------------------
Plan hash value: 918126316

-----------------------------------------------------------------------------------------------

| Id  | Operation                     | Name          | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT              |               |   154 | 17556 |   139(0)| 00:00:02 |

|*  1 |  VIEW                         |               |   154 | 17556 |   139(0)| 00:00:02 |

|   2 |   SQL MODEL ACYCLIC           |               |   154 |  8624 |   |          |

|   3 |    TABLE ACCESS BY INDEX ROWID| SALES_FACT    |   154 |  8624 |   139(0)| 00:00:02 |

|*  4 |     INDEX RANGE SCAN          | SALES_FACT_I1 |   154 |       |     4(0)| 00:00:01 |

-----------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("YEAR"=2000)
   4 - access("COUNTRY"='Australia' AND "PRODUCT"='Xtend Memory')

子查询因子

在商务环境中,需求是很复杂的并且经常需要多个层级的聚合。当书写复杂查询时,将子查询因子化与model子句结合起来,以避免sql语句变得复杂而不易管理。

--记住更多sql数据访问索引的内容
WITH t1 AS (
       SELECT product, country, year, week, inventory, sale, receipts
          FROM sales_fact sf 
          WHERE country IN ('Australia') AND product='Xtend Memory'
          model RETURN updated rows 
          PARTITION BY(product, country) 
          dimension BY(year, week) 
          measures(0 inventory, sale, receipts) 
          rules AUTOMATIC ORDER(
                inventory [ year, week ] ORDER BY year, week =
                  nvl(inventory [ cv(year), cv(week) - 1 ], 0)
                   -sale [ cv(year), cv(week) ] 
                   +receipts [ cv(year),cv(week) ])
)
SELECT product, country, year, week, inventory, sale, receipts, prev_sale
FROM t1
MODEL RETURN UPDATED ROWS
PARTITION BY(product,country)
DIMENSION BY(year,week)
MEASURES (inventory,sale,receipts,0 prev_sale)
RULES SEQUENTIAL ORDER(
 prev_sale[year,week] ORDER BY year,week =
  NVL(sale[cv(year)-1,cv(week)],0)  
)
ORDER BY 1,2,3,4;

小结

写sql语句以集合的思维方式思考,很多sql语句都可以使用model子句来简洁地进行重写。用model子句或分析函数进行查询重写可以获取比传统的sql语句好得多的性能。子查询因子化,model和分析函数特性的结合可以用来有效实现复杂的需求。

相关文章

网友评论

    本文标题:oracle学习笔记9: model子句(下)

    本文链接:https://www.haomeiwen.com/subject/wgissttx.html