Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一次由查询转换引起的性能问题的分析

一次由查询转换引起的性能问题的分析

作者头像
数据和云
发布于 2018-03-08 07:09:02
发布于 2018-03-08 07:09:02
1.1K0
举报
文章被收录于专栏:数据和云数据和云

作者介绍

郭成日 云和恩墨北区技术工程师

专注于SQL审核和优化相关工作。曾经服务的客户涉及金融保险、电信运营商、政府、生产制造等行业。

在优化器进行查询转换的时候,如果将内嵌视图里推入连接谓词,视图里的结果集会更小,优化器就有可能会选择Nested Loops Join 与 Index Range Scan 的方式加快数据的显示。但如果内嵌视图中存在GROUP BY,此时会发生什么情况?在10g和11g里面,Oracle的处理方式有哪些不同?

问题分析

为了解答以上问题,首先需要对SQL的基本语法与查询转换(QueryTransformation)的概念与原理有一定了解。

Oracle优化器可以分为下面两种:

  • Logical Optimizer:是对用户编写的SQL使其转换成让优化器更容易理解的方式的过程。也叫查询转换(QueryTransformation)。
  • Physical Optimizer:对经过Logical Optimizer 转换的SQL,计算成本(Cost),评估并选择最优成本的执行计划的过程。也叫查询优化(Query Optimization)。

基于预估行数或成本选择最优的执行计划的技术,即物理优化器(PhysicalOptimizer) 相关的技术介绍有很多。比如,选择索引还是选择全表扫描、选择Nested Loops Join 还是选择Hash Join 等等都属于这个范畴。使用提示(Hint)改变执行计划也属于这个范畴。但是,相对于查询转换(Query Transformation)相关技术的介绍,与其重要度相比相关技术的介绍就比较少。今天要说明的就是查询转换相关的问题。

这次的问题是内嵌视图中存在GROUP BY时,连接条件谓词无法推入到内嵌视图里。(该问题只是在Oracle 10g里的限制,Oracle 11g已经不存在此问题。)客户正好使用的是10g系统,通过此次问题的分析,可以掌握查询转换问题的基本思路与方法。

测试环境

生成如下表 T1、T2、T3,并插入数据,每个表插入10,000行数据。之后,分别对3个表创建第一个字段C1列的单列索引。最后,收集统计信息。

案列1:GROUP BY 与 Join Predicate Pushing

Oracle 版本是 10.2.0.1的情况。

下面我们看一下内嵌视图里存在GROUPBY时,连接条件谓词无法推入的情况。

以上执行计划分析如下:

  • ID:6,从这里可以看到优化器进行视图合并(View Merge)失败,这是因为内嵌视图里存在ORDER BY的缘故。
  • 连接谓词"T1"."C2"=1,没有进入到内嵌视图内部,即谓词推入失败。优化器把V1视图看成完全独立的查询块(Query Block)。
  • 所以,内嵌视图内部对表T3进行了Full Table Scan,以及对其结果进行Hash Join。

优化器进行视图合并失败时,首先会尝试进行连接条件谓词推入(JoinPredicate Pushing)。上面的SQL文本里可以看到,T1、T2、V1之间存在连接,且存在"T1"."C2"=1,所以满足谓词推入的条件。如果,根据条件"T1"."C2"=1能过滤出很少的结果集,那么谓词推入的效果是相当明显,进一步就可以选择Nest Loops Join ,从而可以用最少的资源得到想要的结果集。

是什么原因导致了谓词推入失败?

下面我们看下在Oracle 11g的情况。

可以看到,执行计划完全改变:

  • ID:6,可以看到VIEW PUSHED PREDICAT,说明优化器进行视图合并(View Merge)失败。
  • 但是,从VIEW PUSHED PREDICAT字面可以理解,连接条件谓词推入成功。
  • ID:9的Predicate Information 里可以看到access("C1"="T2"."C1"),这也进一步说明外面的条件已经进入到视图内部。
  • 所以,因谓词推入的缘故,对表T3出现了INDEX RANGE SCAN,以及对T3的结果集的处理外部选择了NESTED LOOPS JOIN。

这个是因为Oracle 版本的升级解决了老版本优化器的一些限制的典型案例。这种新功能增加往往会带来隐含参数的增加。此处也不例外,请记住这个隐含参数_optimizer_extend_jppd_view_types。如下,可以看到这个隐含参数。

我们可以利用提示(Hint)关闭这个参数,看看会产生什么结果。

可以看到,关闭相应隐含参数的时候,执行计划回到了Oracle 10g时候的样子,即没有进行连接条件的谓词推入。

可以亲眼确认查询转换过程的方法是使用10053的事件。通过10053事件我们推测一下在Oracle10g和Oracle11g里区别是什么。

首先,可以通过Legend了解到产生了哪种查询转换。

可以看到,Oracle 11g里比Oracle 10g 使用了更多的查询转换。Oracle每次的版本更新都会带来查询转换领域的不断更新。

内嵌视图的查询块(SEL$2)里存在ORDER BY语句,所以视图合并失败。这个是两个版本都相同的地方。但是,有趣的是使用的方式不同,Oracle 10g里使用了CVM(Complex ViewMerge),Oracle11g里使用的是SVM(Simple Viewer Merge),说明因版本的升级Oracle里视图合并的基准改变了。

下面的信息可以明确的看到,Oracle 10g里尝试把主查询块(SEL$1)里存在的连接谓词(Join Predicate)推入到内嵌视图的查询块(SEL$2)里,但是因为GROUP BY 语句失败了。

但是,从下面信息中可以看到,在Oracle 11g里连接谓词推入(Join Predicate Push)成功了。这时,通过CBQT(Cost Based Query Transformation)即基于代价的查询转换计算成本(Cost Based),之后判断是否使用连接谓词推入。

从上面的信息中可以看到,连接谓词推入成功。

这个问题虽然看起来很简单, 但是里面使用到的知识点非常得多。对查询转换没有一个基本的理解与认识,对复制SQL语句的调优,会觉得比较困难。下面请再看一个例子。

案列2:UNION ALL 与 Join Predicate Pushing

对存在UNION ALL 语句的视图进行连接谓词推入,也是一个比较常见的情况。

首先,看一个连接谓词推入成功的例子。

可以看到,执行计划里的信息如下:

  • ID:3,可以看到包含UNION ALL 的内嵌视图优化器尝试进行视图合并(View Merge)失败。
  • ID:4,可以看到从UNION ALL PUSHED PREDICATE,连接条件谓词推入成功。
  • 所以,因谓词推入的成功缘故,ID:5和6出现了不是FullTable Scan的 Index RangeScan,出现了更加优越的执行计划。

也就是说,内嵌视图外面的条件"C1"="T3"."C1"推入到UNION ALL视图内部,从而产生了更加优越的执行计划。因为根据条件T3.C2 BETWEEN 1 AND 5 会对T3表产生少量的结果集。所以,后面跟着出现了 Nested Loops Join的情况,这个的前提是连接条件"C1"="T3"."C1"能够推入到视图里,并且选择了Index Range Scan的时候。

如果,使用提示 NO_PUSH_PRED ,防止连接条件谓词推入的发生会怎么样?

下面请再看一下:

从执行计划中可以看到,没有对UNOIN ALL 视图的谓词推入。所以,在ID:5和6选择了非 IndexRange Scan的 Full TableScan。之后,外面也是选择了非NestedLoops Join的 Hash Join。

是否产生连接谓词推入,要看其成本(Cost)是多少,决定权在CBQT(Cost Based Query Transformation)。如果,优化器判断连接谓词推入的成本更高,即使能做谓词推入也不会选择谓词推入。下面我们再看一个例子。把条件换成T3.C2 BETWEEN 1 AND 100 的时候,被选择的行数会增加,有可能会判断出Nested Loops Join的成本会更高。所以,连接谓词推入有可能不会出现。

此次,还可以继续做几个有趣的测试。一般提示FIRST_ROWS是为了让执行计划产生能够快速显示头几行的执行计划而使用。所以,一般内部会倾向于选择Nested Loops Join而非Hash Join,也倾向于选择Index Range Scan 而非Table Full Scan。所以,上面的例子如果加上FIRST_ROWS提示的时候,会有很大几率选择连接谓词推入。结果也确实如下所示。

那么,如果使用提示FIRST_ROWS(1)会如何呢?

FIRST_ROWS(N)提示与FIRST_ROWS不同,是要求快速显示头N行时,产生的执行计划。与FIRST_ROWS提示不同,FIRST_ROWS(N)提示是基于成本的,而非基于规则,即计算N行成本以后选择执行计划。所以,与FIRST_ROWS相比更灵活,但也更不好预测其执行计划的结果。下面可以看到,选择了一个全新的执行计划。

如果,正确理解了连接谓词推入的原理的话,可以使用如下提示LEADING、USE_NL得到相同的结果。选择的路线(PUSH_PRED 与 LEADING + USE_NL)不一样,但是目的地(因谓词推入而选择Index Range Scan与Nested Loops Join)是相同的。

总结

我们看了几个在查询转换(Query Transformation)中非常典型的连接谓词推入的例子。希望在实践中不断进行尝试,来加深对查询转换的理解。优化过程中,经常会问自己为什么不选择索引呢?今后,希望再加上两个问题问自己,为什么不进行谓词推入呢?为什么不进行视图合并呢?对查询转换的认识越深,对执行计划的理解也会变得越来越深,对SQL优化也会变得加更体系化。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据和云 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle里的查询转换
Oracle里的查询转换,有称为查询改写,指oracle在执行目标sql时可能会做等价改写,目的是为了更高效的执行目标sql在10g及其以后的版本中,oracle会对某些类型的查询转换(比如子查询展开、复杂视图合并等)计算成本,oracle会分别计算查询转换后的等价改写的sql的成本和原始sql的成本,如果改写后的sql的成本低于原始sql的成本,oracle才会对目标sql执行查询转换。
星哥玩云
2022/08/17
1.9K0
常见Oracle HINT的用法
Hint概述 基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。
jack.yang
2025/04/05
1050
Oracle处理IN的几种方式
最近看到一些IN语句的优化案例,有些环节不是很理解,重读一下dbsnake的书中关于IN处理方式的介绍,以下内容算是学习笔记。
bisal
2021/01/27
2.1K0
Oracle处理IN的几种方式
Oracle优化06-Hint
在Oracle 10g中,CBO 可选的运行模式有2种: (1) FIRST_ROWS(n) (2) ALL_ROWS – 10g中的默认值
小小工匠
2021/08/16
1.2K0
MySQL8.0发布,你熟悉又陌生的Hash Join?
昨天下午在查资料的时候,无意间点到了MySQL的doc。发现MySQL发布了一个新版本。
王知无-import_bigdata
2020/02/10
8190
极限优化:从75到2000,由技能到性能提升岂止80倍
崔华,网名 dbsnake Oracle ACE Director,ACOUG 核心专家 编辑手记:感谢崔华授权我们独家转载其精品文章,也欢迎大家向“Oracle”社区投稿。 崔华手记:这篇文章的标题颇有些标题党的味道,但这不是我的初衷。其实我想表达的是,基于RDBMS的应用系统的性能问题绝大多数都是和SQL直接相关,而基于Oracle数据库的SQL优化能否奏效、效果的好与坏归根结底比拼的还是对CBO和执行计划的理解程度,这也正是我在《基于Oracle的SQL优化》一书中提出来的SQL优化方法论的第一点
数据和云
2018/03/06
1.4K0
极限优化:从75到2000,由技能到性能提升岂止80倍
GaussDB T 性能调优——SQL问题分析之解读执行计划
查看执行计划 GaussDB T默认开启RBO,开启和关闭CBO需要执行SQL语句。
数据和云01
2020/03/23
1.4K0
GaussDB T 性能调优——SQL问题分析之解读执行计划
MySQL 8.0 新特性:引人注目的哈希连接(Hash Join)
blog.csdn.net/horses/article/details/102690076
肉眼品世界
2020/11/11
7600
MySQL 8.0 新特性:引人注目的哈希连接(Hash Join)
SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势
Hint是Oracle数据库中很有特色的一个功能,是很多DBA优化中经常采用的一个手段。那为什么Oracle会考虑引入优化器呢?基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻DBA的负担。
宜信技术学院
2019/11/12
9.1K0
当心外部连接中的ON子句
       在SQL tuning中,不良写法导致SQL执行效率比比皆是。最近的SQL tuning中一个外部连接写法不当导致过SQL执行时间超过15分钟左右此即 为一例。通过修正该SQL的写法之后,过高的逻辑读呈数量级下降以及SQL语句执行时间也大幅下降。下面给出一个列子来演示该情形。
Leshami
2018/08/14
2.2K0
oracle 查询转换初探
Oracle‍‍查询转换初探 作者‍:邱大龙‍‍ 概述 Oracle查询转换器的作用是把原始sql重写为语义相同的语句,目的是为了获得更高效的sql。 查询转换主要有四种技术:子查询展开,视图合并,谓词推入,星型转换。 了解查询转换是掌握SQL优化的基础,本文将对这四种技术做一些简单的介绍。 子查询展开 子查询展开是指优化器不再把子查询作为独立的单元处理,而是转换成等价的join方式。转换有两种方式:一是将子查询的结果集作为视图,与外层表或视图做join;二是将子查询中的表或视图拆出
沃趣科技
2018/03/23
1.7K0
一个执行计划异常变更的案例 - 外传之SQL Profile(上)
之前的几篇文章: 《一个执行计划异常变更的案例 - 前传》 《一个执行计划异常变更的案例 - 外传之绑定变量窥探》 《一个执行计划异常变更的案例 - 外传之查看绑定变量值的几种方法》 《一个执行计划异常变更的案例 - 外传之rolling invalidation》 《一个执行计划异常变更的案例 - 外传之聚簇因子(Clustering Factor)》 《一个执行计划异常变更的案例 - 外传之查询执行计划的几种方法》 《一个执行计划异常变更的案例 - 外传之AWR》 《一个执行计划异常变更的案例 - 外传之ASH》 《一个执行计划异常变更的案例 - 外传之SQL AWR》 《一个执行计划异常变更的案例 - 外传之直方图》
bisal
2019/01/29
7010
关于查询转换的一些简单分析(一) (r3笔记第37天)
在sql解析器中,在生成执行计划的时候,会在多个执行计划中选择最优的计划,在这个过程中,查询转换就是一个很重要的过程。 虽然最终的执行结果没有变化,但是从优化器的角度来看,查询转换的结果会更好。 大体来说查询转换有以下几种类型。 视图合并 子查询解嵌套 谓词推进 物化视图查询重写 比如 select *from emp where deptno in (select deptno from dept) 会在查询转换中转换为下面的样子. select e.* from emp e,dept d wher
jeanron100
2018/03/14
5810
Oracle优化05-执行计划
如果要分析某条SQL的性能问题,通常来讲,我们首先要看SQL的执行计划,看看SQL的每一步执行计划是否存在问题。
小小工匠
2021/08/16
8280
【DB笔试面试570】在Oracle中,SQL优化在写法上有哪些常用的方法?
一般在书写SQL时需要注意哪些问题,如何书写可以提高查询的效率呢?可以从以下几个方面去考虑:
AiDBA宝典
2019/09/29
3.7K0
分析一个号称拥有“专利”的SQL
先来看一本书(见下图),作者是业界鼎鼎有名的大师级人物Richard Niemiec,从9i、10g到现在的11g,这个优化系列的书,每一本都是厚厚的千页左右,可见大师的称号不是浪得虚名。下面这部最近几年翻译出版的11gR2,书的译者也都是老虎刘非常熟悉和敬佩的几位老朋友,当时也都在甲骨文供职。其中主要的3位译者,杨中是老虎刘在RWP时的老板,朱波和吕学勇在进入甲骨文之前也和老虎刘在同一家公司。这是一本全面介绍Oracle性能相关知识的好书,值得推荐。
老虎刘
2022/06/22
4080
分析一个号称拥有“专利”的SQL
SqlServer的执行计划如何分析?
执行计划是 SQL Server 中的一个重要工具,用于分析和优化查询的性能。它提供了关于查询的详细信息,包括查询的执行顺序、使用的索引、连接类型、过滤条件等。
明志德道
2023/10/21
8950
Oracle优化器对谓词顺序处理的一个场景
最近听了个讲座,其中介绍到了Oracle的谓词,原始版本的例子,如下所示,从数据上能看到,c1='3'的时候,c2的值是个字符串类型的数字,
bisal
2022/03/22
6240
Oracle优化器对谓词顺序处理的一个场景
MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点5:表连接算法(join algorithm)
我们知道对于Oracle的表连接,根据SQL连接条件主要支持如下三种连接方法(算法):
SQLplusDB
2023/08/17
6530
MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点5:表连接算法(join algorithm)
【DB笔试面试615】在Oracle中,和谓词相关的查询转换有哪些?
♣ 题目部分 在Oracle中,和谓词相关的查询转换有哪些? ♣ 答案部分 (一)过滤谓词推入 LHR@orclasm > SELECT * FROM (SELECT * FROM VW_SVM_LHR V) WV WHERE WV.JOB='DBA'; -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |
AiDBA宝典
2019/09/29
8700
相关推荐
Oracle里的查询转换
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档