WITH+HInt MATERIALIZE 不见得有效

本文探讨了Oracle数据库中使用WITH子句与MATERIALIZE提示来优化查询的方法,特别是在减少重复计算和提高查询效率方面的应用。适用于多次使用的子查询场景。
那个要多次调用才需要物化的。
只调用一次,物化没用
MATERIALIZE 
语法:MATERIALIZE 
描述:指示优化器将内联视图实体化————执行过程中会创建基于视图的临时表。

with dd as (select  object_type,owner,object_Id    from dba_objects)
select OBJECT_TYPE, count(*)
  from dd
 group by OBJECT_TYPE
union all
select owner, count(*) from dd group by owner;


with dd as (select /*+materialize */object_type,owner,object_Id from dba_objects)
select OBJECT_TYPE, count(*)
  from dd
 group by OBJECT_TYPE
union all
select owner, count(*) from dd group by owner;

下面有文章介绍其好处

http://www.itpub.net/thread-1443086-1-1.html
WITH子句与未公开HINT MATERIALIZE联合使用, 取代临时表


运行环境:
    ORACLE,  Release 11.2.0.1.0.

描述:
在SQL-99中,查询语句增加了WITH子句,可以使相同的子查询在一个sql中只执行一次,另外也可以把复杂的查询简化、增加可读性。
另外,我们知道利用ORACLE的GTT(GLOBAL TEMPORARY)全局临时表、MATERIALIZE VIEW物化视图来提高查询的效率。
其实我们可以通过WITH与未公开的提示(HINT)MATERIALIZE联合使用,在子查询结果记录数不是太多的情况下,取代GTT和物化视图。

,,,,,,,,

执行结果,花费时间减少一半。
materialize这个hint是oracle没有公开的提示,它指示ORACLE CBO在with子句内物化临时表。这在oracle10g之后是没有必要的,但是实际使用with时,如果发现没有被物化,可以用此hint来强制oracle作此处理,使此子查询(临时表)只被处理一次。


结论:
    在一定的情况下,我们可以用with与hint materialize结合的方式取代全局临时表和物化视图来提高查询效率,使用情况如下。


1.      当次查询的结果记录数不是太多的情况下,如果结果记录集比较庞大,还是推荐使用GTT,因为那里面可以指定索引等。
2.      查询值和查询过滤条件中如果含有重复执行的表达式,可以用此方式减少一次计算。
3.      相同子查询被多次使用。


参考page:
http://www.remote-dba.net/oracle ... with_sql_clause.htm
http://www.dba-oracle.com/t_materialize_sql_hint.htm

我看了下 感觉不是加了物化提示才减少时间 或许是 SELECT /*+ NO_MERGE(V_TMP) FULL(V_TMP) */  * 这提示减少时间吧

深圳-道道(726442711)  17:25:53
加提示之后,就是临时表的形式了

那个要多次调用才需要物化的。
只调用一次,物化没用
MATERIALIZE 
语法:MATERIALIZE 
描述:指示优化器将内联视图实体化————执行过程中会创建基于视图的临时表。 
可以防止 外层谓词内推和内联视图展开.

WITH 语句本身可以共享结果 在同一条语句内  增加物化提示 是否是多余之举 而且是官方非公开的
在 Oracle 中,**CTE(Common Table Expression)结合 `MATERIALIZE` 提示**是一种优化查询性能的技巧,它允许你将 CTE 的结果缓存为临时表,避免重复执行和扫描原始表。 --- ## ✅ 什么是 `WITH ... AS (...)` + `/*+ MATERIALIZE */` ### 1. **CTE(Common Table Expression)** - 是一种定义在 `WITH` 子句中的子查询。 - 可以提高 SQL 的可读性和结构化程度。 - 在 Oracle 中默认是“内联”的,即每次使用都会重新执行。 ### 2. **`/*+ MATERIALIZE */` 提示** - 这是一个 Oracle 优化器提示(Optimizer Hint),用于告诉 Oracle 把 CTE 的结果物化成一个临时表。 - 物化后,后续多次引用该 CTE 时可以直接从临时表中取数据,而不是每次都去查原表,从而提升性能。 --- ## ✅ 使用方法 ### 示例:基本语法 ```sql WITH your_cte_name AS ( SELECT /*+ MATERIALIZE */ column1, column2, ... FROM some_table WHERE condition ) SELECT * FROM your_cte_name; ``` > 注意: > - `/*+ MATERIALIZE */` 要写在 CTE 查询的 `SELECT` 后面。 > - Oracle 并不保证一定物化,但会尽可能尝试这样做。 > - 适用于大表过滤、复杂计算等需要重用中间结果的场景。 --- ## ✅ 示例说明 ### 假设有一个大表 `employees`,我们想提取所有部门编号为 'IT' 的员工信息,并多次使用这个中间结果: ```sql WITH it_employees AS ( SELECT /*+ MATERIALIZE */ employee_id, first_name, last_name, salary FROM employees WHERE department_id = (SELECT department_id FROM departments WHERE department_name = 'IT') ) SELECT * FROM it_employees WHERE salary > 10000; -- 再次使用 it_employees SELECT COUNT(*) FROM it_employees; ``` 在这个例子中: - 第一次查询高薪 IT 员工; - 第二次统计 IT 部门总人数; - 因为用了 `MATERIALIZE`,Oracle 会把 `it_employees` 的结果缓存下来,两个查询都从缓存中获取数据,而不是两次访问原表。 --- ## 🔍 注意事项 | 项目 | 说明 | |------|------| | `MATERIALIZE` 是 hint | Oracle 不保证一定物化,但大多数情况下会生效 | | 不支持递归 CTE | Oracle 12c 开始支持递归 CTE,但 `MATERIALIZE` 对其无效 | | 物化成本 | 如果 CTE 数据量非常小,物化反而可能带来额外开销 | | 适合大数据量或复杂逻辑 | 特别适合频繁被调用、数据量大的中间结果 | --- ## ✅ 与普通 CTE 的区别 | 特性 | 普通 CTE | CTE + MATERIALIZE | |------|----------|-------------------| | 是否缓存结果 | 否 | 是(尽量) | | 多次使用是否重复执行 | 是 | 否(只执行一次) | | 性能影响 | 小数据量无感,大数据量慢 | 更高效 | | 使用建议 | 简单查询 | 复杂、多处引用的中间结果 | --- ## ✅ 相关问题 ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值