专栏名称: DBAplus社群
围绕数据库、大数据、PaaS云,顶级大咖、技术干货,运营几个月受众过十万!成为运维圈最专注围绕“数据”的学习交流和专业社群!欢迎投稿,加入探讨。
目录
相关文章推荐
阿里云大数据AI平台  ·  【5月重点功能发布】阿里云大数据+ AI ... ·  20 小时前  
阿里云大数据AI平台  ·  【5月重点功能发布】阿里云大数据+ AI ... ·  20 小时前  
数据分析与开发  ·  突发!Anthropic 断供 ... ·  23 小时前  
数据中心运维管理  ·  施耐德电气PowerLogic™ ... ·  2 天前  
数据中心运维管理  ·  6月1日起实施!我国首部绿色数据中心评价国标 ... ·  3 天前  
数据中心运维管理  ·  应急预案和应急演练到底怎么做? ·  2 天前  
51好读  ›  专栏  ›  DBAplus社群

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

DBAplus社群  · 公众号  · 数据库  · 2017-05-23 07:26

正文

请到「今天看啥」查看全文



(3)如果只是前通配,可以使用reverse函数索引(不是翻转键索引)


原始语句:
SELECT  * FROM t WHERE t.NAME LIKE '%ORADB1';


创建reverse函数索引,并改写语句, 注意查找值要倒序:




注意: 如果通配查询的是中文,要注意使用REVERSE翻转条件值,因为REVERSE内部会按字节翻转的,正确写法如:


SELECT * FROM t WHERE REVERSE(t.name) LIKE REVERSE('数据')||'%';



否则查询出来的数据不对,将可能影响到业务的正常运行。


索引列使用了函数、数学运算、其他表达式等,走不了索引


解决方法:去掉对索引列的相关运算,保持索引列纯净。


目前优化器对一些数学运算,还无法做很好的消除动作,所以对于索引列应该尽量保持纯净,否则可能无法用上正确的索引。


举例:



把语句的条件改写一下,将运算去掉:



以上例子只是简单的数学运算,可能的运算还有和其他列运算,比如where ID+ext_col...


记住一个原则:尽量保持索引列纯净。


使用了隐式类型转换,走不了索引


解决方法: 必须避免隐式类型转换,全部要求显式类型转换(非索引列),且避免对索引列进行类型转换(有函数索引除外)。如果类型不一致,不管是否发生自动类型转换,谓词的右值应该显式转换为与索引列保持一致(对于非索引列的运算也应该如此)。


举例:




从以上两次查询对比来看,第一次查询发生了类型转换,可以通过执行计划中的谓词信息获知。通过分析发现,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,默认开关关闭。







请到「今天看啥」查看全文