当前位置: 首页 > ai >正文

oracle 数据库sql 语句处理过程

14.1SQL语句处理过程
在进行SQL语句处理优化前,需要先熟悉和了解SQL语句的处理过程。
每种类型的语句在执行时都需要如下阶段:
第1步: 创建游标。
第2步: 分析语句。
第5步: 绑定变量。
第7步: t运行语句。
第9步: 关闭游标。
如果使用了并行功能,还会包含下面这个阶段:
第6步: 并行执行语句。
如果是查询语句,则需要几个额外的步骤:
第3步: 描述查询的结果集。
第4步: 定义查询的输出数据。
第8步: 取查询出来的行。
第1步 创建游标(Create a Cursor) :由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序中创建的游标,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步分析语句(Parse the Statement):在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。
语法分析分别执行下列操作:
(1)翻译SQL语句,验证它是合法的语句,即书写是否正确。
(2)实现数据字典的查找,以验证是否符合表和列的定义。
(3)在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义。验证为存取所涉及的模式对象所需的权限是否满足。决定此语句最佳的执行计划,将它装入共享SQL区。
以上任何一步出错误,都将导致语句报错,中止执行。
只有在共享池中不存在等价SQL语句的情况下,才对SQL语句作语法分析。在这种情况下,数据库内核重新为该语句分配新的共享SQL区,并对语句进行语法分析。进行语法分析需要耗费较多的资源,所以要尽量避免进行语法分析,这是优化的技巧之一。
Oracle只对每个SQL语句翻译一次,在以后再次执行该语句时,只要该语句还在共享SQL区中,就可以避免对该语句重新进行语法分析,也就是此时可以直接使用其对应的执行计划对数据进行存取。这主要是通过绑定变量(bind variable)实现的,也就是常说的共享SQL,后面会给出共享SQL的概念。
虽然语法分析验证了SQL语句的正确性,但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不足等)。因此,有些错误通过语法分析是抓不到的。例如,在数据转换中的错误或在数据中的错(如企图在主键中插入重复的值)以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况。 查询与其它类型的SQL语句不同,因为在成功执行后作为结果将返回数据。
第3步 描述查询结果;描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步定义查询的输出数据:在查询的定义阶段,指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。
第5步: 绑定变量:Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)。
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。
因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。
如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。
第6步:并行执行语句(Parallelize the Statement ):Oracle 可以在DML语句中执行相应并行查询操作,对某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,可以执行并行操作。并行化可导致多个服务器进程为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步执行语句:Oracle拥有所有需要的信息与资源,可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因没有数据需要被改变。如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。
对于某些语句,可以指定执行的次数,这称为批处理。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。
第8步取出查询的行:在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步关闭游标,SQL语句处理的最后一个阶段就是关闭游标。
14.2SQL解析共享原理
Oracle将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享。当执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同,Oracle就能很快获得已经被解析的语句以及最好的执行路径。这个功能大大地提高了SQL的执行性能并节省了内存的使用。
为了不重复解析相同的SQL语句,在第一次解析之后,Oracle将SQL语句存放在内存中。这块位于系统全局区域SGA的共享池中的内存可以被所有的数据库用户共享。因此,当执行一个SQL语句(有时被称为一个游标)时,如果它和之前执行过的语句完全相同,Oracle就能很快获得已经被解析的语句以及最好的执行方案。Oracle的这个功能大大地提高了SQL的执行性能并节省了内存的使用。
可惜的是,Oracle只对简单的表提供高速缓冲,这个功能并不适用于多表连接查询。数据库管理员必须在启动参数文件中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了。当向Oracle提交一个SQL语句时,Oracle会首先在这块内存中查找相同的语句。
要使用内存中共享池的SQL,必须满足以下条件:当前被执行的语句和共享池中的语句必须完全相同 (包括大小写、空格、换行等),两个语句所指的对象必须完全相同 (同义词与表是不同的对象);两个SQL语句中必须使用相同的名字的绑定变量。Oracle对两者采取的是一种严格匹配策略。
能够使用共享的语句必须满足三个条件:
(1)前被执行的语句和共享池中的语句必须完全相同 (包括大小写、空格、换行等)。
(2)两个语句所指的对象必须完全相同 (同义词与表是不同的对象),即两条SQL语句操作的数据库对象必须相同。
(3)语句中必须使用相同命名的绑定变量。如:第一组的两个SQL语句是相同的,可以共享;而第二组中两个语句不同,即使在运行时赋予不同的绑定变量以相同的值:
【例14-1】写两组绑定变量的语句,分析是否可以共享。
第一组代码如下:
select pin,name from people where pin = :blk1.pin;
select pin,name from people where pin =:blk1.pin;
由于语句完全相同,所以第一组的两个SQL语句是相同的,可以使用共享。
第二组代码如下:
select pin,name from people where pin =:blk1.ot_jnd;
select pin,name from people where pin = :blk1.ov_jnd;
由于绑定变量名称不同, 不可以使用共享。
第二组语句每执行一次就需要在SHARE POOL 硬解析一次,一百万用户就是一百万次,消耗CPU和内存,如果业务量大,很可能导致宕库。如果绑定变量,则只需要硬解析一次,重复调用即可。
硬解析是指Oracle在执行目标SQL时,在库缓存中找不到可以重用的解析树和执行计划,而不得不从头开始解析目标SQL并生成相应的父游标和子游标(Child Cursor)的过程。硬解析,生成执行计划需要耗用CPU资源,以及SGA资源。
硬解析过程:
语法、语义及权限检查;
查询转换(通过应用各种不同的转换技巧,会生成语义上等同的新的SQL语句,如count会转为count(*));
根据统计信息生成执行计划(找出成本最低的路径,这一步比较耗时);
将游标信息(执行计划)保存到库缓存。
总结:尽可能的避免硬解析,因为硬解析需要更多的CPU资源,闩等。
尽可能的使用绑定变量来避免硬解析。
cursor_sharing参数应权衡利弊,需要考虑使用similar与force带来的影响。

http://www.xdnf.cn/news/4414.html

相关文章:

  • LeetCode 热题 100_最长回文子串(93_5_中等_C++)(暴力破解法;动态规划)
  • LLaMA-Factory微调DeepSeek-R1-Distill-Qwen-7B
  • 2025年数字藏品行业DDoS攻防指南:技术升级与合规防御双轨制
  • 【C++】类和对象【下】
  • MySQL 中的 MVCC 是什么?
  • SRAM详解
  • vscode 安装插件
  • 软件开发模型介绍
  • MATLAB制作直方图
  • 【25软考网工】第五章(8)路由协议RIP、OSPF
  • QT聊天项目DAY09
  • 【神经网络与深度学习】VAE 中的先验分布指的是什么
  • 嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
  • MySQL从入门到精通(三):MySQL数据类型、SQL语言—DDL
  • 老年综合评估实训室虚拟仿真建设的关键技术与发展路径
  • 【论文阅读】Towards Stable Backdoor Purification through Feature Shift Tuning
  • C++ 完美转发
  • k8s部署OpenELB
  • vue3父组件调用子组件方法
  • AI大模型分类以及Prompt优化技巧
  • Microsoft Azure 在印度尼西亚区域正式上线
  • MDP相关内容
  • JVM中对象的存储
  • AI能否取代软件架构师?我将4个大语言模型进行了测试
  • win11下pip安装matplotlib超时的问题解决
  • PAT(最近)
  • spring cloud gateway 断言(Predicates)与过滤器(filters)
  • 基于vue框架的电子竞技赛事管理系统12t47(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • JVM中类加载过程是什么?
  • FPGA 不兼容故障及处理