你要为难优化器,优化器会加倍为难你

又一个核心系统去IE成功了,操作系统从AIX换为Linux,Oracle数据库从11.2.0.3升级到11.2.0.4,整体CPU利用率稳定运行在10%之内。

 

但是,有一个停复机业务的SQL犹如脱缰的野马,执行时间从几毫秒变到几百秒(执行时间的变化过程中,执行计划没有发生改变,表中的数据有变化),变成升级过程的插曲。本文将详细分析这个SQL的优化过程,展示一个不符合Oracle优化器的SQL语句,扭转起来到底有多费神。

 

 

我们可以看到,在8点15这个snapshot,15分钟内执行了10000多次(一万多次复机),之后每15分钟处理效率极低,只有40次。

 

语句(下述语句均经过脱敏)并不复杂:

 

 

迁移之前,正确的执行计划如下,使用了USER_ID作为关联条件,做一个NL嵌套循环即可完成查询:

 

 

迁移之后,执行计划变了,执行时间从几毫秒暴涨到几十秒上百秒。哪里发生问题了?

 

 

对该语句做一个10053跟踪,看看中间出了什么问题?

 

 

《踩坑CBO,解决那些坑爹的SQL优化问题》一文中,丁俊做了CBO优化器组件的描述:

 

 

从上图可以看出,一条SQL进入Oracle中,实际上经过解析会将各部分进行分离,每个分离的部分独立成为一个查询块(query blocks),比如子查询会成为一个查询块,外部查询又是一个查询块,那么Oracle优化器要做的工作就是各查询块内部走什么样的访问路径更好(走索引、全表、分区?),其次就是各查询块之间应该走什么样的JOIN方式以及JOIN顺序,最终计算出哪种执行计划更好。优化器的核心就是查询转换器、成本估算器以及执行计划生成器。

 

这次遇到的语句之所以执行计划没有走“正确”:本质是subquery unnest没有做成功,导致FILTER失败。而失败的根源是触犯了CBO的底线,跟山东辱母案一样。

 

简单说,由于子查询中包含rowid和distinct,所以视图合并查询失败先执行外层查询,外层查询的每一行驱动执行一次子查询,因为外层条件返回行数高达数万条,因此,子查询被驱动查询数万次,效率低下。

 

通常情况,这种时候我们就会祭出SQL Profile大杀器,在不修改SQL语句的情况下把SQL优化好。这通常是管用的,但是在11.2.0.4里,它跟段誉的六脉神剑一样存在失灵的可能性。很不巧的是,我们运气实在有点好,从少商剑用到少泽剑,所有“原本”可以使用的Profile都失灵了。

 

最后查询转换是由对应参数控制,在我们的优化过程中尝试了SQLTXPLORE,把FIX control接近1200个参数都打开关闭了一下,也没有发现正常执行计划。一般Oracle已经fix的BUG,是可以通过XPLORE发现并解决的,然而这条SQL没有发现正常计划。

 

因此,这个问题是Oracle为了避免在类似这种SQL中写ROWID故意限制的,那么对开发编写SQL有什么启发呢?要符合规范,特别是关键字最好要用别名。

 

接下来我们谈谈SQL的改写。

 

SQL改写一:with查询物化
 

传统的方法都不能用,那么我们就尝试着改写SQL语句。语句本身并不复杂,操作都在一张表内完成(要查询2次),从停复机接口表中抽出最近一天产生的停机用户,排除去重,给出ROWID,复机服务根据ROWID去复机。

 

所以兄弟们想到一个临时解决方案,将第一个子查询结果物化:

 

 

执行计划如下:

 

 

这个执行计划跟没有改写前的形式很像,区别在于将子查询结果物化,进而提升了语句效率。

 

实际生产运行看,基本效率没有问题,但是在业务小高峰,存在一定积压的时候,性能会有些许异变。

 

SQL改写二:官方怎么看
 

Oracle MOS文章Query Referencing ROWID ofSubquery With Join Fails With ORA-01445(文档 ID1929880.1)中,详细说明了开发商原来的SQL语句写法存在问题。

 

 A rowid is only defined for individual rows in a table, so it is not legal to select a rowid from a subquery unless each row from that subquery can be guaranteed to be uniquely associated with exactly one row in one table.  Therefore, the subquery may have only one item in its FROM list; that item must also have a rowid; and the subquery must not use DISTINCT, GROUP BY, or anything else that might gather multiple rows into one.

 

简单翻译一下:rowid仅仅用来明确识别表中的特定行,因此除非能保证从子查询中查询出的每一行能够与表中的一条记录严格一一匹配,否则在子查询中使用rowid是不合法的(不符合Oracle要求的)。也就是说,子查询输出中能且仅可以有一个输出项,这个输出项可以有一个rowid,并且这个子查询中不可以有DISTINCT、GROUP BY或其他可能会将多个行变为一个行的关键字。

 

很不幸,我们的语句里,既有ROWID还有DISTINCT。

 

参考Oracle给出的解决方案:

 

 

参照,对原生产SQL语句做第二次改写(重复部分忽略)。改成JOIN方式,避免子查询相关查询转换,同时里层用别名,外层用ROWID交付给其他服务接口使用:

 

 

执行计划:

 

 

我们可以看到,执行计划重新用回了NL嵌套循环。COST值有变化,其中一个表用到了全表扫描,但是应为表大小总量可控,整体效率性能依然很高。

 

SQL改写三:元芳怎么看?
 

波波同学深入研究了业务逻辑,提出了一种创新思路,整个SQL建议改写为:

 

只对停复机接口表做一次查询,该表数据量本身不大(记录数通常在10万以内),是否走索引效率都会很高。

 

 

所以优化器理解起来就更容易,执行计划也就更简单,效率更高。

 

修改语句的逻辑是,在没有业务积压的情况下,复机顺序不严格按照停机顺序进行,只要处理得够快,复机时间早或者晚个几毫米对最终用户来说是无感知的。

  

这个案例说到这里,有没有给你带来什么启示?

 

从问题发生到结案,DBA团队尝试过索引重建、统计信息搜集、HINT、重建表、SQL profile绑定等多种方式,最终通过SQL改写解决。

 

对于DBA来说,不仅仅要懂得数据库的基本原理、基本技术,还应该更加多往业务端走一走,懂业务的DBA会更加高效、卓越。

 

我们之所以要去开发SQL审核平台,初衷就是要让开发/应用程序的SQL语句书写更合规,更加按照符合数据库的优化器行为去做,将潜在问题扼杀在萌芽状态。

 

并且,只有通过大量类似的大规模客户案例的充实,才能让SQL审核平台越来越臻于完善,SQL审核的有效识别率从80%提升到90%,以及更多。

 

原文发布时间为:2017-03-29

 

时间: 2024-11-04 20:14:56

你要为难优化器,优化器会加倍为难你的相关文章

rtmp-安卓手机上vlc播放器优化

问题描述 安卓手机上vlc播放器优化 vlc播放自己的直播摄像网络视频,一开始我们改进后从点击到画面显示最快速度可以到2秒内启动,但是后来发现两个问题: 1.没有声音播放出来 2.随着播放时间越久延时越来越厉害 为了解决这两个问题,改进之后启动就需要7秒左右了,请问哪位大神能优化启动速到在3秒左右或者更短,前提是保证有声音和延时没太大问题 解决方案 我做的在VLC上的二次开发,用开播放网络监控视频也是遇到了播放延时很严重的问题,针对这个问题我现在的想法是对VLC的解码进行优化,具体怎么做还没开始

ProGuard 4.8发布 Java优化和混淆器

ProGuard 是一款开源的Java类,用于文件的压缩.优化.混淆,预校验.它支持检测和删除未使用的类.字段.方法和属性,优化字节码和删除未使用的指令,使用短无意义的名称重命名剩下的类.字段和方法,预校验Java 6或Java微型版的处理代码.相比与其他Java shrinkers和混淆器,ProGuard的优势是更紧凑的基于模板配置.内存效率和速度. ProGuard 4.8该版本主要修复了配置解析.优化和混淆的一系列小问题.增加了几个字符串优化的优化步骤,小的改进和配置Ant任务.与以前的

DB2性能优化圣经——优化准则

在制定一个性能优化总体方案时,应当考虑下列准则: 1.牢记缩减回报定律最大的性能收益通常来自最初的努力.以后的修改一般只产生越来越小的效益,并且需要付出更多的努力. 2.不要为了优化而优化优化是为了解除一致的约束.如果优化资源不是引起性能问题的主要原因,那么除非接触了主要约束,否则这种优化对响应时间几乎不产生影响,而且这种优化实际上会使后续优化工作变得更加困难.如果有任何重要的潜在改进因素的话,就在于改进某些资源的性能,这些资源是影响响应时间的主要因素. 3.考虑整个系统永远不能只有话一个参数或

ASP.NET性能的优化:网站优化需要考虑的方面

导读:作者燕洋天写了一系列关于ASP.NET的文章.我有段时间没有写ASP.NET的东西了,心里总是觉得缺少了什么,毕竟自己对ASP.NET还是情有独钟的.在本系列文章中,准备比较全面的讲述ASP.NET的性能的优化,从前台到后台,以后本列文也看作为大家的一个手册来查询!以下是文章内容: 网站优化需要考虑的方面 在用ASP.NET开发网站的时候,性能是永远需要考虑和关注的问题,性能不仅仅只是程序代码执行时候的速度,而是涉及到方方面面的东西. 就拿ASP.NET的一个请求来讲,从浏览器向服务器的A

与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成

原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页][源码下载] 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 作者:webabcd 介绍与众不同 windows phone 7.5 (sdk 7.1) 之媒体 音频播放器 视频播放器 与 Windows Phone 的音乐

网站优化到底优化的是什么?

企业建设网站的最终目的是为了实现在线网络销售,广泛的说就是响应当时代网络营销的主题.从狭隘的角度来考虑,网站优化的效果直接影响了网站营销的绩效.讲到这里,笔者小丹要问大家一个问题,网站优化到底优化的是什么?亦或者说我们要从哪些方面来进行网站优化呢?看到这个问题估摸绝大多数人想到的都是SEO优化技巧吧!而针对网站营销真的就仅此而已嘛?显然是不太可能的! 网站营销要想获得在线成果,那网站本身的质量,行业信任度则是必不可少的.而这些也就是我们网站优化工作正在的着手点了.下面就和笔者小丹一起来了解一下网

seo优化-百度优化疑难问题解答

seo优化-百度优化疑难问题解答   1:网站百度快照出现"您访问的网站需要调用JS框架访问"之类的话,网站也是没任何问题,经过老末的研究排除了各种原因后确认是因为网站被人cc攻击后,服务器上开了冰盾防火墙引起的,使得蜘蛛无法完全爬到网站,因为很多sf站都调用js框架发布sf信息的,所以百度在浏览网站出错的时候会读取到一个出错的字符串,就是这个"您访问的网站需要调用JS框架访问"之类的话,快照也会变成这个,排名也会有所倒退,其实只要把冰盾关闭就行了,我朋友这么做以后

网站优化+网店优化+移动优化 亿玛客SEO课程三剑合璧

中介交易 SEO诊断 淘宝客 云主机 技术大厅 网站优化+网店优化+移动优化 亿玛客SEO课程三剑合璧----吴文元老师谈<SEO网站优化>课程升级 前言:2013年3月,亿玛客网络营销课程全新升级,在新的课程体系中,融入了网店运营.电子商务和移动营销等众多内容,更加系统专业.以下是亿玛客吴文元老师关于<网站优化>>(亿玛客网络营销课程第二模块)课程升级访谈记录的整理: 问:亿玛客在课程体系升级中加入了移动网站的优化,请问移动网站优化具体是指的什么? 吴文元老师:移动网站优化

对于博客SEO优化的优化到底该怎么做

摘要: 在经过这一段时间的观察,个人觉得搜索引擎出现了改变,以至于很多站长们都不得不使用一些另类的方法,因为博客的SEO优化是大家都非常重视的一个方面,那么我们应该如何做好 在经过这一段时间的观察,个人觉得搜索引擎出现了改变,以至于很多站长们都不得不使用一些另类的方法,因为博客的SEO优化是大家都非常重视的一个方面,那么我们应该如何做好SEO博客优化呢?博客SEO优化的方法其实很多,大家也没必要沉溺于搜索引擎陷阱. 发现这样一个现象,就是很多站长朋友在做博客SEO优化的时候,大都不知道应该如何去

蔡旭:道法术器,器是末流,多考虑“道”

摘要: 12月5日,车易拍联合创始人蔡旭在亿邦动力网主办的第九届中国网上零售年会上表示,当互联网来临的时候,没有哪个行业不能触碰,做事情必须找到痛点才有机会,道法术器,器是末 12月5日,车易拍联合创始人蔡旭在亿邦动力网主办的"第九届中国网上零售年会"上表示,当互联网来临的时候,没有哪个行业不能触碰,做事情必须找到痛点才有机会,道法术器,器是末流,不要用战术上的勤奋弥补你战略上的懒惰,多考虑"道". 据了解,本届大会已于今日在重庆世纪金源大饭店隆重召开.会议围绕&q