问题描述
嗨,
我有这样的观点
我希望Oracle能够优化以下查询并仅在一个表上执行选择,因为id值作为恒定值提供-
但是执行计划显示从两个基础表中进行选择-
还有什么有趣的-它使用奇怪的过滤表达-
谓词信息 (由操作id标识):
---------------------------------------------------
4-过滤器 (NULL不为NULL)
它看起来像Oracle optimizer忽略了基于视图的常数值的表限制的可能性。可能有一些变通办法吗?我的目标是在几个相似的表的顶部创建一个单一的视图,而不是表名中不同的几个select语句使用一个由表id参数化的select语句。我想最小化我的代码的另一个词,同时不要在不必要的表上添加扫描。
即,而不是
使用简单的代码
我有这样的观点
create view V_TAB as (select 1 as id, value from TAB1 union all select 2 as id, value from TAB2 );复制
我希望Oracle能够优化以下查询并仅在一个表上执行选择,因为id值作为恒定值提供-
select * from V_TAB where id=1;复制
但是执行计划显示从两个基础表中进行选择-
------------------------------------------------------ | Id | Operation | Name | ------------------------------------------------------ | 0 | SELECT STATEMENT | | | 1 | VIEW | | | 2 | UNION-ALL | | | 3 | TABLE ACCESS FULL | TAB1 | |* 4 | FILTER | | | 5 | TABLE ACCESS FULL | TAB2 | ------------------------------------------------------复制
还有什么有趣的-它使用奇怪的过滤表达-
谓词信息 (由操作id标识):
---------------------------------------------------
4-过滤器 (NULL不为NULL)
它看起来像Oracle optimizer忽略了基于视图的常数值的表限制的可能性。可能有一些变通办法吗?我的目标是在几个相似的表的顶部创建一个单一的视图,而不是表名中不同的几个select语句使用一个由表id参数化的select语句。我想最小化我的代码的另一个词,同时不要在不必要的表上添加扫描。
即,而不是
if p_id=1 then select count(*) into cnt from TAB1; elsif p_id=2 then select count(*) into cnt from TAB2; else cnt := 0; end if;复制
使用简单的代码
select count(*) into cnt from V_TAB where id=v_id;复制
专家解答
但是数据库is能够根据需要优化您的查询!
虽然这两个表都可能出现在您的计划中,但它只在运行时访问一个。
谓词NULL不为NULL => false。这意味着它不执行此过滤器下的操作。
您可以通过查看execution计划查询。这显示了它的运行时统计信息:
请注意,对于Id 4,开始列和A行列如何显示零?这意味着双重扫描从未发生过!
虽然这两个表都可能出现在您的计划中,但它只在运行时访问一个。
谓词NULL不为NULL => false。这意味着它不执行此过滤器下的操作。
您可以通过查看execution计划查询。这显示了它的运行时统计信息:
create or replace view V_TAB as (select 1 as id, dummy from dual union all select 2 as id, dummy from dual ); set serveroutput off select /*+ gather_plan_statistics */* from V_TAB where id=1; select * from table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST')); PLAN_TABLE_OUTPUT SQL_ID 66w0ahf4hk0p4, child number 0 ------------------------------------- select /*+ gather_plan_statistics */* from V_TAB where id=2 Plan hash value: 3824994890 ----------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | | 1 | VIEW | V_TAB | 1 | 2 | 1 | | 2 | UNION-ALL | | 1 | | 1 | |* 3 | FILTER | | 1 | | 0 | | 4 | TABLE ACCESS FULL| DUAL | 0 | 1 | 0 | | 5 | TABLE ACCESS FULL | DUAL | 1 | 1 | 1 | ----------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter(NULL IS NOT NULL)复制
请注意,对于Id 4,开始列和A行列如何显示零?这意味着双重扫描从未发生过!
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
601次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
587次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
494次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
478次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
463次阅读
2025-04-22 00:20:37
Oracle 19c RAC更换IP实战,运维必看!
szrsu
439次阅读
2025-04-08 23:57:08
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
437次阅读
2025-04-22 00:13:51
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
428次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
371次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
360次阅读
2025-04-15 14:48:05