APP下载

Oracle中的SQL语句共享研究

2015-01-29杨国勋

新媒体研究 2014年22期

杨国勋

摘 要 在软件应用系统设计和开发的过程中,容易被设计者所忽视的就是如何通过增加数据库SQL语句共享来提高系统的整体性能,本文通过深入研究Oracle数据库中SQL语句的解析过程,分析了SQL语句不能共享的主要原因,并给出如何增加SQL语句共享率的解决方案。

关键词 SQL语句共享;软解析;硬解析

中图分类号:TP311 文献标识码:A 文章编号:1671-7597(2014)22-0069-01

Oracle数据库是目前在中大型软件项目中应用最为广泛的数据库之一,在这样一些项目中需要处理的数据量是非常巨大的,而且用户对应用系统的性能要求比较高。提高系统的性能一方面是需要有一个良好的架构设计,另一方面则是要提高底层数据库系统的性能。数据库性能的提升需要由经验丰富的DBA来配置和维护,但更重要而且是容易被忽视的是程序员在编写代码时需要提高数据库系统的SQL语句共享率,避免不必要的SQL语句硬解析,从而降低系统在进行SQL语句解析花费的时间和资源。

1 SQL语句解析过程

Oracle处理客户端应用程序提交过来的SQL语句主要分为4个阶段,SQL语句解析、参数绑定、执行和获取结果,其中SQL语句解析是其中非常重要的一个阶段,理解这个阶段的处理过程对于提高应用系统整体性能有很好的帮助。

在SQL语句的解析阶段,Oracle会进行如下操作:

检查SQL语法错误:检查SQL语句中的关键字是否有拼写错误,顺序和位置是否正确等。

检查SQL语义错误:检查该SQL语句引用的对象是否存在,提交SQL语句的用户是否具有访问该对象的权限等。

SQL共享语句查询:Oracle数据库服务器管理程序会先在服务器会话缓存用户全局区(UGA)中查询是否有此SQL语句对应的已打开的游标(Open Cursor),如果有则通过已打开游标中的指针找到在服务器共享池(Shared Pool)中的此SQL语句对应游标句柄并执行,此时不需要对语句进行解析,因为打开的游标已经被解析,而且游标句柄已经存在于服务器共享池的库缓存(Library Cache)中。

如果游标被关闭,则游标的信息会被保存在会话关闭游标的缓存中,此缓存的大小是由参数SESSION_CACHED_CURSORS决定的。当系统在UGA中没找到SQL语句对应的已打开的游标,则会在已关闭游标缓存中查询,如找到匹配的已关闭游标,则会重新打开此游标,通过此游标可以直接执行SQL语句而不需要重新解析。

如果系统在UGA中没找到此SQL语句的游标,则会根据SQL语句生成的Hash值在Shared Pool中的Hash链中查询是否有此SQL语句对应的游标句柄,如果此游标句柄能够找到且游标的其他信息没有丢失,则可以执行此SQL语句,此次查询过程被系统记录为一次解析,但不是真的解析,因此这个过程也被称为软解析。

硬解析:如果此SQL语句在UGA和Shared Pool中都没有找到匹配的游标,则Oracle服务器系统需要在Library Cache中为此SQL语句创建一个父游标(parent cursor)和一个子游标(child cursor)。父游标中包含了SQL文本和对应的Hash值,父游标的信息可以通过视图v$sqlarea查询。子游标中包含了使得这个SQL可以执行的所有相关信息,如执行权限、优化器设置和执行计划等。子游标的信息可以通过视图v$sql进行

查询。

2 SQL语句无法共享原因分析

通过对SQL语句在Oracle中的解析过程研究可以知道,SQL语句无法共享主要是由两个原因造成,父游标无法共享以及子游标无法共享。

1)父游标无法共享。

父游标能够共享的前提条件是SQL语句对应的Hash值要一致,Oracle系统在生成SQL语句Hash值的时候是会区分大小写和空格,如下面几条SQL语句虽然查询含义一样,但写法没有统一使得Hash值不一致而造成SQL语句无法共享。

select * from tb_student where id=1

select * from TB_STUDENT where id=1

select * from tb_student where id=1

2)子游标无法共享。

当SQL语句及其Hash值一致时就可以共享父游标,但有时会因为种种原因使得子游标无法共享,此时同一个父游标会有多个子游标,子游标的个数可以通过视图v$sqlarea的version_count字段查询处理。在实际的项目中,要尽量避免version_count过高的情况。子游标无法共享的一个常见原因是绑定变量不一致,这里的变量不一致,有可能是变量名不一致,也有可能是变量对应的数据类型的长度不一致,例如,对于字符类型的字段,进行绑定变量的时候,如果该变量值小于32字节的话,第一次会使用32字节的缓冲区,第二次执行这个SQL的时候,如果该值小于32字节,那么可以共享这个子游标,如果大于32字节就无法共享,此时会在同一父游标下创建一个新的子游标,同时分配128字节的缓冲区。子游标另外一个无法共享的常见原因是SQL语句查询选择的优化器模式不一致。子游标无法共享的原因可以通过查询视图v$sql_shared_cursor进行分析。

3 增加SQL语句共享率

通过上述分析,要增加SQL语句共享率,提高系统的整体性能可以从以下几方面入手:

1)SQL语句在文本上必须完成相同,包括空格、换行、大小写都必须完全相同,因此在项目组中要制定SQL语句的书写规范,使得不同的程序员在编写程序时按照统一的SQL语句规范来书写,增加SQL语句共享,减少SQL语句硬解析的次数,提高应用程序的执行效率。

2)在书写SQL语句的时候尽量使用绑定变量的方式,并且保证变量名和变量数据类型字段长度一致。在进行SQL语句查询时,尽量选择一致的优化器模式。

3)设置SESSION_CACHED_CURSORS参数为一个恰当的值,从而保证被关闭的游标能在服务器缓存中保存一段时间,增加SQL语句共享的几率。

参考文献

[1]张江.Oracle数据库的性能优化策略浅析[J].现代计算机(专业版), 2012(36).

[2]赵琛.Oracle服务器性能影响因素分析与优化[J].电脑编程技巧与维护,2011(20).endprint