当前位置: 首页 > news >正文

/*+ MATERIALIZE */ 优化器提示在 WITH 子句中的使用验证

Oracle /*+ MATERIALIZE */ 优化器提示在 WITH 子句中的使用验证

概述

/*+ MATERIALIZE */是 Oracle 数据库的优化器提示(Hint),核心作用是强制将 WITH 子句(公共表表达式,CTE)的查询结果物化到临时表中。当后续查询多次引用该 CTE 时,可直接复用临时表数据,避免重复执行子查询;即使仅引用一次,也能通过该 Hint 强制触发物化行为。

测试场景与验证

场景 1:重复引用子查询(非 WITH 子句)—— 无临时表物化

当相同子查询被多次直接引用(未封装到 WITH 子句)时,Oracle 优化器不会将子查询结果物化到临时表,每次引用都会重新执行子查询。

SELECTmain.cust_id,main.cust_name,main.order_summary,sub1.vip_countFROM(SELECTc1.cust_id,c1.cust_name,SUM(o.order_amount)ASorder_summaryFROM(SELECTcust_id,cust_name,cust_levelFROMcustomersWHEREtotal_consume>50000)c1LEFTJOINorders oONc1.cust_id=o.cust_idGROUPBYc1.cust_id,c1.cust_name)mainCROSSJOIN(SELECTCOUNT(*)ASvip_countFROM(SELECTcust_id,cust_name,cust_levelFROMcustomersWHEREtotal_consume>50000)c2WHEREc2.cust_level='VIP')sub1

执行计划结论:预估执行计划中未使用临时表空间,子查询被重复执行。
在这里插入图片描述

场景 2:重复引用 WITH 子句中的 CTE—— 触发物化

将重复执行的子查询封装到 WITH 子句中,多次引用该 CTE 时,Oracle 会自动将 CTE 结果物化到临时表。

WITHcAS(SELECTcust_id,cust_name,cust_levelFROMcustomersWHEREtotal_consume>50000)SELECTmain.cust_id,main.cust_name,main.order_summary,sub1.vip_countFROM(-- 第一次引用 cSELECTc1.cust_id,c1.cust_name,SUM(o.order_amount)ASorder_summaryFROMc c1LEFTJOINorders oONc1.cust_id=o.cust_idGROUPBYc1.cust_id,c1.cust_name)mainCROSSJOIN(-- 第二次引用 cSELECTCOUNT(*)ASvip_countFROMc c2WHEREc2.cust_level='VIP')sub1

执行计划结论:CTE 的结果集被物化到临时表中,后续引用直接复用临时表数据。

场景 3:单次引用 WITH 子句中的 CTE—— 不触发物化

若 WITH 子句中的 CTE 仅被引用一次,Oracle 优化器默认不会将结果集物化到临时表,而是直接执行子查询。

WITH c AS (SELECT cust_id, cust_name, cust_level FROM customers WHERE total_consume > 50000) SELECT main.cust_id, main.cust_name, main.order_summary FROM ( -- 仅一次引用 c SELECT c1.cust_id, c1.cust_name, SUM(o.order_amount) AS order_summary FROM c c1 LEFT JOIN orders o ON c1.cust_id = o.cust_id GROUP BY c1.cust_id, c1.cust_name) main

执行计划结论:预估执行计划中无临时表物化行为,CTE 子查询直接执行。

场景 4:单次引用 +/*+ MATERIALIZE */ Hint—— 强制物化

在 WITH 子句的 CTE 中添加/*+ MATERIALIZE */Hint,即使 CTE 仅被引用一次,也能强制 Oracle 将结果集物化到临时表。

测试 SQL

sql

WITH c AS (SELECT /*+ MATERIALIZE */ cust_id, cust_name, cust_level FROM customers WHERE total_consume > 50000) SELECT main.cust_id, main.cust_name, main.order_summary FROM ( -- 仅一次引用 c SELECT c1.cust_id, c1.cust_name, SUM(o.order_amount) AS order_summary FROM c c1 LEFT JOIN orders o ON c1.cust_id = o.cust_id GROUP BY c1.cust_id, c1.cust_name) main

执行计划结论:CTE 结果集被强制物化到临时表中。

场景 5:Hint 直接写在普通子查询中 —— 无效

/*+ MATERIALIZE */Hint 直接添加到非 WITH 子句的普通子查询中,无法触发物化行为。

执行计划结论:实验验证该方式无效,临时表物化未发生。

三、结论

  1. /*+ MATERIALIZE */仅对WITH 子句内的 CTE生效,直接写在普通子查询中无物化效果;
  2. WITH 子句中的 CTE 被多次引用时,Oracle 会自动物化结果到临时表;仅被单次引用时,默认不物化;
  3. 即使 CTE 仅单次引用,也可通过在 WITH 子句的 CTE 查询中添加/*+ MATERIALIZE */Hint,强制将结果集物化到临时表,适用于优化器判断失误时,未将结果集物化到临时表的情况。
  4. 需要复用子查询结果或优化执行效率的场景。
http://www.jsqmd.com/news/339937/

相关文章:

  • MOMENT:时间序列预测、分类、异常检测的基础模型
  • 单声道到立体声:AI 如何为音乐注入新生命
  • 移动开发:利用 Gradle 进行代码混淆配置
  • 刘德华女儿高调亮相,太漂亮了吧,恐怕是娱乐圈颜值最高的星二代了
  • 企业AI转型困境,AI应用架构师路线图来拯救
  • 短剧收稿编辑的福音:2026年AI 评剧本让优质剧本脱颖而出
  • 使用GD32F103C8T6开发板的标准库实现硬件I2C协议通信(附源码下载地址)
  • 语音转写还能识情绪?SenseVoiceSmall让你大开眼界
  • 2026年1月份国内3D打印行业11起融资,最高超亿元
  • 2026年口碑好的O型圈高分厂家推荐 - 行业平台推荐
  • 再也不用手动配环境了,这个镜像全包了
  • 软件库APP开源Flutter SoftLib源码 带后端源码
  • 短视频内容打标:笑声密集段自动标记为‘搞笑’
  • 全新个人发卡网源码 无需支付接口
  • 《计算机网络》深入学:自治系统 (Autonomous System)
  • Banana Vision Studio入门指南:快速掌握4种工业美学方案
  • react笔记之useCallback如何增加代码复杂度和内存开销
  • 通义千问3-4B优化技巧:让AI推理速度提升3倍
  • Qwen3-VL-Reranker-8B应用场景:医疗影像报告图文混合语义检索系统
  • 一篇文章带你走进测试工程师的世界
  • 世毫九实验室RAE递归对抗引擎:技术与原理全解
  • 软件测试十几个可以练手的项目实战,力推原创
  • 信通院:人工智能产业发展研究报告(2025年) 2026
  • 测试新手百科:Postman简介、安装、入门使用方法详细攻略!
  • 14:00面试,14:06就出来了,问的问题有点变态。。。
  • Claude Code 内部团队的10大隐藏技巧曝光!每一个都会让你眼前一亮。
  • 【ICLR26-金连文-华南理工】OMNI-IML: 迈向统一的可解释图像篡改定位
  • 世毫九实验室简介·方见华致各界书
  • QT4C-Windows自动化测试框架正式开源
  • SAM 3 图像和视频