oracle去掉谓词推入,消除谓词推进
今天,还是用第一篇博文的例子,看下怎么消除谓词推进。首先先上图,这是一个发生了谓词推进的例子。
sql:
SELECT
COUNT(1) AS count
FROM (
SELECT a.ykf272, a.akb020, a.akb021,
a.yka094, a.ake005
, a.yke936, a.ykf282, a.aac003, a.aac001, a.aac002
, a.akc225, a.akc226, a.ykf275, a.ykf281,
a.ykf284
, a.ykf283, a.yke453, a.aae011, a.aae036,
a.yke923
, a.yke925, a.yab003, b.yka059, b.yka002,
b.yke627
, b.yka095, a.yke938, a.yke940, x.ake006
, pkg_common.fun_getAaa103('YKF062',
x.ykf062) AS ykf062
, (
SELECT c.aaa103
FROM bm_ykf063 c
WHERE b.ykf063 = c.ykf063
) AS ykf063, b.yka007, x.ykf064
, (
SELECT
pkg_common.fun_getAaa103('AKA070', c.aka070)
FROM ka02 c
WHERE b.yka002 = c.yka002
) AS aka070, pkg_common.fun_getAaa103('YKE469',
b.yke469) AS yke469, b.aka074
FROM kz37k1 a, ka05 b,(
SELECT
akb020, ake005, yka094, ake006, ykf062
,
ykf064
FROM
(
SELECT
x.akb020, x.ake005, x.yka094, x.ake006, x.ykf064
,
x.ykf062, DENSE_RANK() OVER (PARTITION BY x.akb020, x.ake005, x.yka094 ORDER BY
aae030 DESC) AS r
FROM
kb05k1 x
)
WHERE
r = 1
)
x
WHERE a.yka094 = b.yka094
AND a.akb020 = x.akb020
AND a.ake005 = x.ake005
AND a.yka094 = x.yka094
AND a.akb020 = '855855'
AND a.yab003 = '0001'
AND trunc(a.aae036, 'dd') >=
'08-APR-18'
AND trunc(a.aae036, 'dd') <=
'10-APR-18')a;
执行计划:
我们看到id=7这里发生了谓词推进。我们来看下谓语信息。
注意到id=7那里只是一个filter,所以谓词推进并不是发生在这一步,这里只是告诉你标黄的子查询部分发生了先被谓词推入然后作为一个整体参与后续的步骤。那真正发生谓词推入的地方在哪里呢?可以看到id=7到id=11最先执行的应当是id=11,而且这里循环了43782次,
也就是说,这一步索引范围扫描重复了43782次,我们往上看与第7步并列的是id=3,他们的父步骤id=2就是嵌套循环,而id=3最终得到的结果集(这一步的a-rows)就是43782行,这就不奇怪了,id=3的结果集作为驱动表,而id=7的结果集作为被驱动表,确实该发生这么多次循环,
但问题是,id=7的这个结果集并不是作为一个整体被遍历了43782次,而是从索引范围扫描就开始循环了,这是为什么呢?
我们看到sql中标黄部分的子查询,完全可以自成一体,只遍历一次,就可以得到想要结果集,为什么要遍历43782次,(这里其实是已经做过优化的,之前是max()函数,自联结的一个查询,为了不让这里被多次遍历,用分析函数优化了自联结),这时候我们就该看看id=11的谓词信息是什么,
id=11显示走了index_..._AKE005的索引,谓词信息表明它具体走了索引的哪写列,发现本该在where条件中的x表和a表的连接条件出现在了这里,这就是导致这里发生了43782次循环的根源,这里发生的就是谓词推入,把本不该是子查询的条件推入到子查询中,明显这里不适合这样做。
现在我们发现了问题的原因,那么怎么能阻止谓词推入呢?我们去找找outline部分里面对应该行为的hint。
找到了,就是这里,所以很简单了,我们只需要把这句复制出来,把push_pred改成no_push_pred,然后再把它加入到第一个select后面的hint中。
现在我们再看执行计划:
我们看到id=4的starts列变为1,表明这个子查询现在是按照我们理想的只执行了一次。
小结一下:
谓词推入是cbo一种优化的行为,但是谓词推入并不总是好的,如果谓词被推入后缩小了结果集,降低了逻辑读,那就是好的,反之就不太好,其实cbo并不是只要有谓词推入的机会就会推入,由于统计信息不准确,倾斜的列上没有直方图,都会导致cbo在计算cost
的时候产生较大偏差,而对于大的业务表,数据变化频繁,也不能总收集统计信息,所以这时候我们就需要去找到合适的hint来协助cbo做出最优的选择。
oracle去掉谓词推入,消除谓词推进相关推荐
- oracle 谓词是什么意思,Oracle谓词推入
在Oracle中,谓词一般就是指where后面的那些过滤条件. 而在执行计划中,我们有时候会看到一个信息: VIEW PUSHED PREDICATE 就是传说中的谓词推入. 谓词推入是什么意思? 就 ...
- Oracle查询转换之连接谓词推入
连接谓词推入(Join Predicate Pushdown)是优化器处理带视图的目标SQL的一种优化手段,它是指虽然优化器会把该SQL中视图的定义SQL语句当作一个独立单元来单独执行,但此时优化器 ...
- Oracle NO_PUSH_PRED 不使用谓词推入
Oracle Hint No PUSH PRED The NO_PUSH_PRED hint instructs the optimizer not to push a join predicate ...
- oracle 谓词推入失效,oracle view 谓词推入
数据量描述: select count(*) from VIW_A --28403614 视图 select count(*) from VIW_B --3960249 视图 select c ...
- [20150710]11G谓词推入问题2.txt
[20150710]11G谓词推入问题2.txt --生产系统遇到一个sql语句的问题. --生产系统的sql语句比较复杂,做一个简化的例子来说明问题.来说明自己优化遇到的困惑. --昨天看来别人的回 ...
- VIEW PUSHED PREDICATE(谓词推入)引发的惨剧
帮网友调SQL http://www.itpub.net/forum.php?mod=viewthread&tid=1492997&extra=pageD1%3D&page=1 ...
- Oracle 12CR2查询转换之谓词推送
在谓词推送中,优化器将包含在查询块中的相关谓词推送到视图查询块中.对于不能合并的视图,这种技术可以提高不能合并视图的执行计划.数据库可以使用推送谓词来访问索引或作为过滤. 例如,假设创建了一个hr.c ...
- oracle合计去掉重复,关于oracle 去掉重复数据问题
关于Oracle去除重复数据: 1):Oracle的row_number() over函数消除重复的记录 例子:1.select d.id,d.outer_code from dict_depts_s ...
- Oracle 去掉重复字符串
create or replace function remove_same_string(oldStr varchar2, sign varchar2) return varchar2 is/*** ...
最新文章
- Python 2 和 3 的区别及兼容技巧
- DJANGO用户名认证一例
- 干货 | 携程基于Quasar协程的NIO实践
- MariaDB [Warning] Could not increase number of max_open_files to more than 1024
- Binary Tree Non-recursive Traversal
- 常见索引结构—跳跃表
- c++运动学正反解 ros_朔州智能【机器人关节臂】哪家强
- paip.php页面调试设置及流程
- 各种数据库之间数据迁移工具
- 学习笔记:云计算安全CCSK
- oracle 更改归档位置,oracle更改归档路径
- webstorm下载破解
- 后缀数组(倍增)学习记录,我尽可能详细的讲了
- 怎样卸载腾讯网页游戏微端服务器,如何删除腾讯页游微端启动器
- 董明珠用 3.1 亿的带货成绩,刷新了许多人对直播电商的认知
- Jquery 动画效果 左右移动
- 快速启动栏增强工具 Free Launch Bar
- Kindle电子书资源网站汇总 转自豆瓣
- openvas(开放式漏洞评估系统)
- office 字体大小选择,没有 一号二号等中文字体