加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 安全 > 正文

由索引未被使用,看SQL开发规范落地

发布时间:2021-01-16 07:49:31 所属栏目:安全 来源:网络整理
导读:副标题#e# 《由索引未被使用,看SQL开发规范落地》要点: 本文介绍了由索引未被使用,看SQL开发规范落地,希望对您有用。如果有疑问,可以联系我们。 作者介绍 王科,新炬网络架构师.Oracle OCM,10年以上运维管理经验,擅长运维服务与运维工具的融合应用,在数

从以上两次查询对比来看,第一次查询发生了类型转换,可以通过执行计划中的谓词信息获知.通过分析发现,X因为是VARCHAR2,优先级比数值类型低,遇到数值类型,会TO_NUMBER隐式转换,所以索引失效.第二次查询,通过传入与索引列类型一致的字符串后,得以解决.

查询转换失败,走不了索引

查询转换是非常复杂的过程,ORACLE CBO的查询转换有好几十种,比如CVM :complex view merging,SU:subquery unnest,JPPD:JOIN PREDICATE PUSH DOWN等(在10053文件里都可以看到).如果查询转换失败,那么必将影响后续优化器的一些操作,比如JPPD中JOIN谓词无法推入到视图中,那么很可能视图就无法走索引了.而且,查询转换有很多BUG,触发BUG需要找到原因,比如设置隐含参数、fix control等,或者改写SQL绕过BUG.如下例所示:

其中AB_XRTOFFREC_201703是UNION ALL查询组成的视图,这个查询在10.2.0.4上很正常,升级到11.2.0.4后执行计划显示不走索引,性能非常差.

在10g中的执行计划:

在11g中的错误执行计划:

通过收集统计信息都无效,将优化器降级到10.2.0.4即有效.很显然,这是引入了BUG或者新的限制.一旦遇到这种是BUG或限制导致的,可以通过10053跟踪文件或者SQLT来进行分析.对于这条语句无法走JPPD查询转换,在10053中就可以找到原因:

然后在MOS中查看得知是BUG:9380298,默认开关关闭.

 

ORACLE针对这样的查询,为了防止遇到笛卡尔积,默认把修复BUG的补丁关闭了.显然通过设置_fix_control参数打开9380298 fix即可.

语句逻辑问题,导致优化器选择不了索引

举一个典型的例子,先准备测试表,并在其上创建一个组合索引:

查询需求:查找创建时间是2013年的,并且最后ddl时间比创建时间大1天以上的对象.

这个索引是组合索引,上面的语句对前导列进行了运行,也不符合走index skip scan的条件,所以,走FULL TABLE SCAN.那么是否可以通过逻辑改写走索引呢,基于保持索引列纯净的原则,将create_date移到右边,语句如下:

改写后发现,还是没有走索引,因为Oracle认为前导列右边的created不固定,无法从指定索引处查找.通过分析得知,Oracle谓词传递有一定限制,create_date+1无法做谓词传递给last_ddl_time.再次改写:

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!