解决Oracle SQL语句性能问题——SQL语句改写(视图、标量子查询及update)

这篇具有很好参考价值的文章主要介绍了解决Oracle SQL语句性能问题——SQL语句改写(视图、标量子查询及update)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们在前述文章中也已经提到,对于高版本的关系库,尤其是针对Oracle这样的关系库,绝大多数场景下,同一语义和结果的SQL语句的具体语法,不会成为SQL语句执行计划的影响因素,但在少数场景下,针对同一语义和结果的SQL语句的不同写法,数据库优化器最终会分别为其生成不同的执行计划。因此,当一条SQL语句的执行计划不理想时,为了改变该SQL语句的执行计划,我们会考虑改写相应SQL语句,从而达到调优目的。下面,具体介绍通过SQL语句改写进行调优的方法和相关内容。

1. 消除视图(view)

视图可以简化应用的研发和维护,还可以满足安全性方面的需求。但在有些场景中,视图会为应用埋下性能隐患,尤其在大数据量业务中,大量且多层次嵌套使用视图的场景。为了消除性能隐患和优化性能,有时需要我们改写包含视图的SQL语句,分解并消除其中的相关视图,具体改写方法如下所示。

--改写前

SQL> create view v_test as

select * from tab1 where col1=...;

SQL> select * from tab2 t2,tab3 t3,v_test v

where t2.col1=t3.col1

and t3.col1=v.col1

and v.col2=...;

--改写后

SQL> select * from tab2 t2,tab3 t3,tab1 t1

where t2.col1=t3.col1

and t3.col1=t1.col1

and t1.col2=...

and t1.col1=...;

--注:

      1)消除视图时需要注意的事项。

  • 是否符合视图分解和消除条件,有些场景的视图,是没办法分解和消除的。
  • 要把和原视图相关的select list中相关项,更换为原视图相应基表的列名。
  • 要把原视图内的where条件和主查询合并。
  • 要把原主查询中视图相关的条件更换为视图相应基表列的相关条件。

      2)消除视图的适用场景,包括但不限于如下场景。

  • 原SQL语句主查询from中连接数据对象比较多,且原SQL语句存在性能问题。
  • 原SQL语句的视图子查询from中连接数据对象比较多,且原SQL语句存在性能问题。
  • 原SQL语句中视图嵌套层数比较多,且原SQL语句存在性能问题。

      3)设计实验并做测试。

  • 获取分解消除视图前后的执行计划,并比较思考分解消除视图前后的变化和利弊。
  • 注意分解消除视图前后,执行计划中join相关节点(见本书第7章)的变化,执行计划的整体调整和变化。
  • 如果分解消除视图前后的执行计划没有变化,大家思考下,没有发生变化的原因,以及导致可能发生变化的场景和因素。

2. 标量子查询改为外连接

包含标量子查询的SQL语句,看上去思路清晰、逻辑分明且易于理解,但在很多场景中,标量子查询会导致其相关SQL语句的严重性能问题。因此,为了解决相关SQL语句的性能问题,有时我们需要对SQL语句进行改写,并消除相关的标量子查询,以对相关SQL语句进行性能优化,具体改写方法如下所示。

--改写前

SQL> select t1.col1,

(

select col2

from

(

select t2.col1,sum(t2.col2) col2 

from tab2 t2

group by t2.col1

) t3 

where t3.col1=t1.col2

) col2_sum

from tab1 t1

where t1.col3=...;

--改写后

SQL> select t1.col1,t3.col2 col2_sum

from tab1 t1,

(

select t2.col1,sum(t2.col2) col2 

from tab2 t2

group by t2.col1

) t3

where t1.col2=t3.col1(+)

and t1.col3=...;

--注:

      1)标量子查询改写为内嵌视图时需要注意的事项。

  • 是否符合改写和消除标量子查询的条件。
  • 原标量子查询下沉为内嵌视图时,需要和原主查询表进行outer join。
  • 原SQL语句中存在多个标量子查询时,应该分别改为相应内嵌视图并下沉,同时,分别和原主查询表进行outer join。
  • 原SQL语句中存在多个标量子查询时,分别改为相应内嵌视图,下沉并进行outer join后,原主查询select-list中各标量子查询相关的列,改为相应内嵌视图的列。

      2)标量子查询改写为内嵌视图的适用场景,包括但不限于如下场景。

  • 原SQL语句中包含标量子查询,且原SQL语句存在性能问题。
  • 原SQL语句中包含标量子查询,且原SQL语句消耗较多系统资源。

      3)设计实验并做测试。

  • 获取改写和消除标量子查询前后的执行计划,并比较分析改写和消除标量子查询前后的变化和利弊。
  • 注意观察分析相关SQL语句改写前后,子查询执行次数的变化和执行计划的整体变化。

3. update改为merge into

update作为DML语句之一,现实工作中,被数据库及研发相关人员广泛使用。但在某些场景中,update语句会导致严重的性能问题。基于上述场景,为了解决update语句导致的性能问题,有时我们需要将update语句改写为merge into语句,以消除导致性能问题的因素,优化和提升相关应用性能。

2014年,某行业机构相关人员对线上产品某核心模块重构、测试后,按计划在生产环境中进行替换,不料,期间发生严重性能问题,导致整个应用系统异常,用户无法使用。本人接到技术支援求助后,连夜通过该数据库的相关信息进行问题跟踪、分析和诊断,确定该故障由重构后的新应用模块导致,并在各方相关人员的协助下,在线对生产环境中该应用模块进行了修改和替换,即将该模块中一个update语句修改为merge into语句。之后,经本人和相关各方人员跟踪和观察,之前性能问题消失,相关应用模块性能提升近千倍。

此外,除了解决性能问题,某些场景中,merge into语句也能很好的解决某些特殊的业务需求。2016年,通过merge into语句,本人帮助某行业机构产品研发团队成功解决了跨时段详单汇聚问题,这样,既避开了原计划在大数据量、高并发频繁操作的核心业务表上,建立触发器可能带来性能等多方面问题的风险,又大幅提高了相应模块的性能,简化了应用逻辑和实现方法,为今后系统的管理和维护打下了良好的基础。关于update语句改写为merge into语句,具体改写方法如下所示。

--改写前

SQL> update tab1 t1 set col2=

(

select col2

from tab2 t2

where t1.col1=t2.col1

)

where t1.col3=...;

--改写后

SQL> merge into tab1 t1

using tab2 t2

on

(

t1.col1=t2.col1

)

when matched then

update set t1.col2=t2.col2

where t1.col3=...;

--注:

      1)update语句改写为merge into语句时需要注意的事项。

  • 是否符合update语句改为merge into语句的改写条件。
  • 确定好两个行源的关系,并按照merge into语句的语法确保进行正确的修改。
  • 确定好两个行源的连接条件,并按照merge into语句的语法确保进行正确的修改。
  • 高版本Oracle中,对merge into语句功能提供了更加强大的支持,具体请参考官方或其他相关文档。

      2)update语句改写为merge语句的适用场景,包括但不限于如下场景。

  • update语句中存在相关子查询,且update语句存在性能问题。
  • 必须通过merge into语句来解决某些特殊的业务需求。

      3)设计实验并做测试。

  • 获取update语句改写为merge into语句前后的执行计划,并比较分析改写前后的变化和利弊。
  • 注意观察分析update语句改写为merge into语句前后,原相关子查询执行次数的变化和执行计划的整体变化。
  • 请大家编写一条merge into语句,其中,既完成update操作,也完成insert等多个操作。

      4)大家可以在update语句改写为merge into语句,与改写及消除标量子查询之间,比较和分析两者的区别和联系。

      5)大家思考和实验,是否可以用解决标量子查询性能问题的办法来解决该update语句的性能问题,并比较分析其中原因。文章来源地址https://www.toymoban.com/news/detail-692744.html

到了这里,关于解决Oracle SQL语句性能问题——SQL语句改写(视图、标量子查询及update)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Oracle数据库SQL*Plus命令行执行SQL语句时,中文乱码报错解决方法

    Oracle数据库SQL*Plus命令行执行SQL语句时,中文乱码报错解决方法

    🎉欢迎来到Java学习路线专栏~Oracle数据库SQL*Plus命令行执行SQL语句时,中文乱码报错解决方法 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:Java学习路线 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹

    2024年01月22日
    浏览(11)
  • SQL语句创建视图:

    SQL语句创建视图:

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言初阶 🔑个人信条: 🌵知行合一 🍉本篇简介::介绍数据库中有关视图的知识,参考学校作业. 金句分享: ✨找不到答案的时候,就找自己。✨ 定义 : 根据用户的各种需求重新构造表的数据结构,这种数据结构就是

    2023年04月08日
    浏览(8)
  • sql创建查询视图语句

    sql创建查询视图语句

    学生表 c表 s表 sc表   --1.查询全体学生的学号,姓名与年龄 SELECT sno,sname,age=year(getdate())-year(sbirth) FROM S; --2.查询计算机系(CS)的学生学号,姓名 SELECT sno,sname FROM S WHERE sdept=\\\'计算机\\\'; --3.查询计算机系所有的女生姓名和年龄 SELECT sname,age=(year(getdate())-year(sbirth)) FROM S WHERE sdept

    2024年02月05日
    浏览(12)
  • ORACLE实时SQL监控视图

    ORACLE实时SQL监控视图

           实时的SQL监控(Real Time SQL Monitoring)是Oracle 11g的一个新特性,它是一项强大的工具,用于监视和分析正在执行的SQL语句的性能和执行计划。该功能允许我们实时地跟踪SQL查询的执行过程,以及了解其资源消耗、等待事件和执行计划等关键指标。         在当今

    2024年02月16日
    浏览(14)
  • 数据库sql语句(视图的创建)

    数据库sql语句(视图的创建)

    例题:  建表:要注意各表之间的索引联系,建表先后顺序很重要,不然建不了,例如先建dept,在建其他表,先在dept插入数据,再在其他表插入数据 (1) (2)  (3)  (4) (5)    插入数据如下图 sql语句: 在 Student 表中加入属性 SAGE(INT 型 )  将 Student 表中的属性 SA

    2024年02月04日
    浏览(48)
  • 4.2.1 SQL语句、索引、视图、存储过程

    怎么执行一条select语句 1.连接器 接收连接-》管理连接-》校验用户信息 2.查询缓存 kv存储,命中直接返回,否则继续执行 8.0已经删除 3.分析器 词法句法分析生成语法树 4.优化器 指定执行计划,选择查询成本最小的计划 5.执行器 根据执行计划,从存储引擎获取数据,并返回客

    2024年02月06日
    浏览(12)
  • GreatSQL 优化技巧:将 MINUS 改写为标量子查询

    GreatSQL 优化技巧:将 MINUS 改写为标量子查询

    minus 指令运用在两个 SQL 语句上,取两个语句查询结果集的差集。它先找出第一个 SQL 所产生的结果,然后看这些结果有没有在第二个 SQL 的结果中,如果在,那这些数据就被去除,不会在最后的结果中出现,第二个 SQL 结果集比第一个SQL结果集多的数据也会被抛弃。 这两天的

    2024年04月08日
    浏览(8)
  • 使用SQL获取oracle表结构语句(DDL语句)

    要获取Oracle数据库中特定库(Schema)中对象的DDL语句,可以使用以下SQL查询来获取指定对象的DDL: 获取表(Table)的DDL语句: 将 \\\'Your_Schema_Name\\\' 替换为你要查询的Schema名称,将 \\\'Your_Table_Name\\\' 替换为你要查询的表名称。 获取视图(View)的DDL语句: 将 \\\'Your_Schema_Name\\\' 替换为你要

    2024年02月05日
    浏览(12)
  • SQL进阶(2)——SQL语句类型 & 增删改查CRUD & 事务初步 & 表关联关系 & 视图 +索引

    SQL进阶(2)——SQL语句类型 & 增删改查CRUD & 事务初步 & 表关联关系 & 视图 +索引

    1.SQL语句的类型,数据操作语句,数据查询语句; 2.MySQL的运算符,常用函数,增删改查CRUD语法; 3.数据操作的事务:原子性,一致性,隔离性,持久性; 4.数据库表关联关系,一对一,一对多,多对多; 5.视图,索引; SQL程序语言有四种类型,对数据库的基本操作都属于这

    2024年02月16日
    浏览(9)
  • MySQL、Oracle 常用SQL:建表、建视图、数据增删改查、常用condition

    删除表:DROP TABLE TABLE_NAME; 建表:CREATE TABLE TABLE_NAME(); 主键:PRIMARY KEY 不为空: NOT NULL 默认值:DEFAULT DEFAULT_VALUE MySQL、Oracle 通用样例: 注意:DATATYPE 是指 数据库的数据类型,需要修改成具体数据类型。 INT类型 自增:INT AUTO_INCREMENT 注释:COMMENT 参考案例: INT类型:不支持自

    2024年01月16日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包