请教这里的高手朋友,oracle的存储过程的执行原理和执行过程是怎样的?

[复制链接]
查看11 | 回复9 | 2013-7-18 13:55:12 | 显示全部楼层 |阅读模式
请教这里的高手朋友,oracle的存储过程的执行原理和执行过程是怎样的?
请教这里的高手朋友,oracle的存储过程的执行原理和执行过程是怎样的、

就是说,oracle 具体如何到share_pool中去找的,这个过程是怎么进行的?
这个对象的状态是如何维护的?
如果失效了,oracle会怎么办?
失效原因是什么啊
请赐教
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
路过,顶起来,一直关注。。。。。。。。。。。
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
在内存中失效,一般的原因都是这个存储过程依赖的某个对象被改变了,一个过程依赖的所有对象都会在那些对象上加一个不会影响任何进程使用的锁,目的是如果这些依赖的对象的定义有任何改变,就要使这个存储过程失效。
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
原帖由 jiqixiaomao 于 2009-2-25 09:17 发表
在内存中失效,一般的原因都是这个存储过程依赖的某个对象被改变了,一个过程依赖的所有对象都会在那些对象上加一个不会影响任何进程使用的锁,目的是如果这些依赖的对象的定义有任何改变,就要使这个存储过程失效。

那么某个存储过程他的内部执行步骤是怎么样的?比方说:一个sql语句提交后,oracle首先在share_pool中查找,如果未找到,则解析,编译这个语句,然后执行,若第二次有提交了相同的语句,oracle直接从内存中取出来执行(所谓的命中,不用重新解析)
不知我理解的对不对?
对于存储过程是怎么回事,请高手指点,讨论啊
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
我也想知道??????????????
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
这个问题很难吗,怎么没人讨论啊
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
导入导出会使对象失效吗?
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
对象失效了,Oracle会重新编译和load的,如果是SQL语句,那么它会硬解析。 很多操作都会导致对象失效,比如truncate啊什么的,具体的我记不太清楚了
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
贴点现成的资料:
每种类型的语句都需要如下阶段:
? 第1步: Create a Cursor 创建游标
? 第2步: Parse the Statement 分析语句
? 第5步: Bind Any Variables 绑定变量
? 第7步: Run the Statement 运行语句
? 第9步: Close the Cursor 关闭游标
如果使用了并行功能,还会包含下面这个阶段:
? 第6步: Parallelize the Statement 并行执行语句
如果是查询语句,则需要以下几个额外的步骤,如图 3所示:
? 第3步: Describe Results of a Query 描述查询的结果集
? 第4步: Define Output of a Query 定义查询的输出数据
? 第8步: Fetch Rows of a Query 取查询出来的行
下面具体说一下每一步中都发生了什么事情:.
第1步: 创建游标(Create a Cursor)
由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步:分析语句(Parse the Statement)
在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。
语法分析分别执行下列操作:
􀁺 翻译SQL语句,验证它是合法的语句,即书写正确
􀁺 实现数据字典的查找,以验证是否符合表和列的定义
􀁺 在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
􀁺 验证为存取所涉及的模式对象所需的权限是否满足 9
􀁺 决定此语句最佳的执行计划
􀁺 将它装入共享SQL区
􀁺 对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
以上任何一步出现错误,都将导致语句报错,中止执行。
只有在共享池中不存在等价SQL语句的情况下,才对SQL语句作语法分析。在这种情况下,数据库内核重新为该语句分配新的共享SQL区,并对语句进行语法分析。进行语法分析需要耗费较多的资源,所以要尽量避免进行语法分析,这是优化的技巧之一。
语法分析阶段包含了不管此语句将执行多少次,而只需分析一次的处理要求。Oracle只对每个SQL语句翻译一次,在以后再次执行该语句时,只要该语句还在共享SQL区中,就可以避免对该语句重新进行语法分析,也就是此时可以直接使用其对应的执行计划对数据进行存取。这主要是通过绑定变量(bind variable)实现的,也就是我们常说的共享SQL,后面会给出共享SQL的概念。
虽然语法分析验证了SQL语句的正确性,但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不足等)。因此,有些错误通过语法分析是抓不到的。例如,在数据转换中的错误或在数据中的错(如企图在主键中插入重复的值)以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况。
查询语句的处理
查询与其它类型的SQL语句不同,因为在成功执行后作为结果将返回数据。其它语句只是简单地返回成功或失败,而查询则能返回一行或许多行数据。查询的结果均采用表格形式,结果行被一次一行或者批量地被检索出来。从这里我们可以得知批量的fetch数据可以降低网络开销,所以批量的fetch也是优化的技巧之一。
有些问题只与查询处理相关,查询不仅仅指SELECT语句,同样也包括在其它SQL语句中的隐含查询。例如,下面的每个语句都需要把查询作为它执行的一部分:
INSERT INTO table SELECT...
UPDATE table SET x = y WHERE...
DELETE FROM table WHERE...
CREATE table AS SELECT...
具体来说,查询
? 要求读一致性
? 可能使用回滚段作中间处理
? 可能要求SQL语句处理描述、定义和取数据阶段
第3步: 描述查询结果(Describe Results of a Query)
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步: 定义查询的输出数据(Define Output of a Query)
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。 10
第5步: 绑定变量(Bind Any Variables)
此时,Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。
因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。
如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档,如Oracle Call Interface Programmer's Guide
第6步: 并行执行语句(Parallelize the Statement )
ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作,对于某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,也可以执行并行操作。并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步: 执行语句(Run the Statement)
到了现在这个时候,Oracle拥有所有需要的信息与资源,因此可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因为没有数据需要被改变。然而,如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。
对于某些语句,你可以指定执行的次数,这称为批处理(array processing)。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。
第8步: 取出查询的行(Fetch Rows of a Query)
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步: 关闭游标(Close the Cursor)
SQL语句处理的最后一个阶段就是关闭游标
DDL语句的处理(DDL Statement Processing)
DDL语句的执行不同与DML语句和查询语句的执行,这是因为DDL语句执行成功后需要对数据字典数据进行修改。对于DDL语句,语句的分析阶段实际上包括分析、查找数据字典信息和执行。
事务管理语句、会话管理语句、系统管理语句只有分析与执行阶段,为了重新执行该语句,会重新分析与执行该语句。
事务控制(Control of Transactions)
一般来说,只有使用ORACLE编程接口的应用设计人员才关心操作的类型,并把相关的操作组织在一起,形成一个事务。一般来说,我门必须定义事务,这样在一个逻辑单元中的所有工作可以同时被提交或回滚,保证了数据的一致性。一个事务应该由逻辑单元中的所有必须部分组成,不应该多一个,也不应该少一个。
? 在事务开始和结束的这段时间内,所有被引用表中的数据都应该在一致的状态(或可以被回溯到一致的状态)
? 事务应该只包含可以对数据进行一致更改(one consistent change to the data)的SQL语句
例如,在两个帐号之间的转帐(这是一个事务或逻辑工作单元),应该包含从一个帐号中借钱(由一个SQL完成),然后将借的钱存入另一个帐号(由另一个SQL完成)。这2个操作作为一个逻辑单元,应该同时成功或同时失败。其它不相关的操作,如向一个帐户中存钱,不应该包含在这个转帐事务中。
在设计应用时,除了需要决定哪种类型的操作组成一个事务外,还需要决定使用BEGIN_DISCRETE_TRANSACTIO存储过程是否对提高小的、非分布式的事务的性能有作用。
回复

使用道具 举报

千问 | 2013-7-18 13:55:12 | 显示全部楼层
原帖由 silentBeauty 于 2009-2-25 23:17 发表
贴点现成的资料:
每种类型的语句都需要如下阶段:
? 第1步: Create a Cursor 创建游标
? 第2步: Parse the Statement 分析语句
? 第5步: Bind Any Variables 绑定变量
? 第7步: Run the Statement 运行语句
? 第9步: Close the Cursor 关闭游标
如果使用了并行功能,还会包含下面这个阶段:
? 第6步: Parallelize the Statement 并行执行语句
如果是查询语句,则需要以下几个额外的步骤,如图 3所示:
? 第3步: Describe Results of a Query 描述查询的结果集
? 第4步: Define Output of a Query 定义查询的输出数据
? 第8步: Fetch Rows of a Query 取查询出来的行
下面具体说一下每一步中都发生了什么事情:.
第1步: 创建游标(Create a Cursor)
由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步:分析语句(Parse the Statement)
在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。
语法分析分别执行下列操作:
􀁺 翻译SQL语句,验证它是合法的语句,即书写正确
􀁺 实现数据字典的查找,以验证是否符合表和列的定义
􀁺 在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
􀁺 验证为存取所涉及的模式对象所需的权限是否满足 9
􀁺 决定此语句最佳的执行计划
􀁺 将它装入共享SQL区
􀁺 对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
以上任何一步出现错误,都将导致语句报错,中止执行。
只有在共享池中不存在等价SQL语句的情况下,才对SQL语句作语法分析。在这种情况下,数据库内核重新为该语句分配新的共享SQL区,并对语句进行语法分析。进行语法分析需要耗费较多的资源,所以要尽量避免进行语法分析,这是优化的技巧之一。
语法分析阶段包含了不管此语句将执行多少次,而只需分析一次的处理要求。Oracle只对每个SQL语句翻译一次,在以后再次执行该语句时,只要该语句还在共享SQL区中,就可以避免对该语句重新进行语法分析,也就是此时可以直接使用其对应的执行计划对数据进行存取。这主要是通过绑定变量(bind variable)实现的,也就是我们常说的共享SQL,后面会给出共享SQL的概念。
虽然语法分析验证了SQL语句的正确性,但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不足等)。因此,有些错误通过语法分析是抓不到的。例如,在数据转换中的错误或在数据中的错(如企图在主键中插入重复的值)以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况。
查询语句的处理
查询与其它类型的SQL语句不同,因为在成功执行后作为结果将返回数据。其它语句只是简单地返回成功或失败,而查询则能返回一行或许多行数据。查询的结果均采用表格形式,结果行被一次一行或者批量地被检索出来。从这里我们可以得知批量的fetch数据可以降低网络开销,所以批量的fetch也是优化的技巧之一。
有些问题只与查询处理相关,查询不仅仅指SELECT语句,同样也包括在其它SQL语句中的隐含查询。例如,下面的每个语句都需要把查询作为它执行的一部分:
INSERT INTO table SELECT...
UPDATE table SET x = y WHERE...
DELETE FROM table WHERE...
CREATE table AS SELECT...
具体来说,查询
? 要求读一致性
? 可能使用回滚段作中间处理
? 可能要求SQL语句处理描述、定义和取数据阶段
第3步: 描述查询结果(Describe Results of a Query)
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步: 定义查询的输出数据(Define Output of a Query)
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。 10
第5步: 绑定变量(Bind Any Variables)
此时,Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。
因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。
如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档,如Oracle Call Interface Programmer's Guide
第6步: 并行执行语句(Parallelize the Statement )
ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作,对于某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,也可以执行并行操作。并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步: 执行语句(Run the Statement)
到了现在这个时候,Oracle拥有所有需要的信息与资源,因此可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因为没有数据需要被改变。然而,如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。
对于某些语句,你可以指定执行的次数,这称为批处理(array processing)。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。
第8步: 取出查询的行(Fetch Rows of a Query)
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步: 关闭游标(Close the Cursor)
SQL语句处理的最后一个阶段就是关闭游标
DDL语句的处理(DDL Statement Processing)
DDL语句的执行不同与DML语句和查询语句的执行,这是因为DDL语句执行成功后需要对数据字典数据进行修改。对于DDL语句,语句的分析阶段实际上包括分析、查找数据字典信息和执行。
事务管理语句、会话管理语句、系统管理语句只有分析与执行阶段,为了重新执行该语句,会重新分析与执行该语句。
事务控制(Control of Transactions)
一般来说,只有使用ORACLE编程接口的应用设计人员才关心操作的类型,并把相关的操作组织在一起,形成一个事务。一般来说,我门必须定义事务,这样在一个逻辑单元中的所有工作可以同时被提交或回滚,保证了数据的一致性。一个事务应该由逻辑单元中的所有必须部分组成,不应该多一个,也不应该少一个。
? 在事务开始和结束的这段时间内,所有被引用表中的数据都应该在一致的状态(或可以被回溯到一致的状态)
? 事务应该只包含可以对数据进行一致更改(one consistent change to the data)的SQL语句
例如,在两个帐号之间的转帐(这是一个事务或逻辑工作单元),应该包含从一个帐号中借钱(由一个SQL完成),然后将借的钱存入另一个帐号(由另一个SQL完成)。这2个操作作为一个逻辑单元,应该同时成功或同时失败。其它不相关的操作,如向一个帐户中存钱,不应该包含在这个转帐事务中。
在设计应用时,除了需要决定哪种类型的操作组成一个事务外,还需要决定使用BEGIN_DISCRETE_TRANSACTIO存储过程是否对提高小的、非分布式的事务的性能有作用。

我是说以前好好的一个存储过程已编译好(系统运行了一年多了),最近发现存储过程失效,那么oracle会不会自动重编译它?
在一种情况:
强制flush库缓存,原来已有的对象被清除了,如果这时oracle又要调用这个对象(存储过程),会有什么情况发生?,系统报错还是oracle重新编译它?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行