前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >96 - or exists写法分析与优化方法

96 - or exists写法分析与优化方法

作者头像
老虎刘
发布2022-12-09 21:43:29
6290
发布2022-12-09 21:43:29
举报

偶然看到一个国产数据库的SQL优化介绍:

下面分析一下这两种写法的优劣:

原or exists写法(写法1):

如果test表结果集小(不含or条件), 那么最终返回的结果集也小,如果test_bak表的object_id字段上有索引, 这种情况是不需要改写的. 如果test_bak表比较大, 改写后反而性能会变差(可能没有merge和push_pred这些查询转换, 大表test_bak要先全表扫描去重, 这个消耗是比较大的).

上面left join改写(写法2)比较适合的场景是:

test表结果集大, test_bak结果集大, 最终结果集也大的情况, 两表可以做hash join, 避免主表做大量filter操作导致性能很差.

上面的改写还漏掉了一个比较重要而且常见的情况, 那就是test表结果集大, 最终结果集小的场景, 这个场景在OLTP系统也是比较常见的, 这种情况改成union all是最佳的(写法3):

select * from test where owner='SCOTT'

union all

select * from test where exists

(select 1 from test_bak where test.object_id=test_bak.object_id)

and lnnvl(owner='SCOTT');

需要特别注意的是: 是用union all改写, 不是union.

回到oracle数据库, 在版本12.2 前, 也要根据上面规则做对应的改写;

在12.2及以上版本,如果写法1效率差, 而且数据分布符合写法3 , 可以不需要改写, 而是通过or_expand的hint让优化器根据指示, 做出查询转换变成写法3; 如果数据分布符合写法2, 还是需要手动改写.

OLTP系统返回一般返回的结果集小, 写法1和写法3 总有一个是适用的 , 而且hint是可以应用到某个具体SQL的. 所以在12.2之后, 不太复杂的 or exists 基本上就不存在性能问题了. 如果是复杂的or exists , 那就要根据情况见招拆招了.

文中观点仅代表本人, 如有不妥, 请指正, 感谢!

全文完

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

本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档