对SQL语句进行调整,往往有一项前期工作,就是定位最常用的SQL 语句。Oracle数据库可以从多个方面取得SQL语句。如从数据库自身的存储过程或者函数中取得,也可以从前台的应用程序中取得。所以,数据库管理员必须学会如何从数据库当前程序库缓存中对已经存在的SQL语句进行采样。了解当前使用最频繁的SQL语句以及其对应的资源消耗情况。只有如此,数据库管理员才能够对症下药,解决SQL语句执行效率不高的问题。
在Oracle数据库中有多种方法可以帮助数据库管理员定位常用的SQL语句。笔者在这里介绍比较常用的两种方法。
一、查询系统表sys.wrh$_sqlsta。
在数据库系统中有如下一张表。这张表存储中Oracle数据库执行过的SQL语句的相关情况。
如上面这张表中,他会反映某个特定Sql语句的执行信息。其中第一个参数Excutions_Total参数纪录了某条SQL语句总共执行的次数。而第二个参数Disk-Reads-Totali参数则统计了从磁盘中读取数据的次数。当SQL语句的执行次数特别多而且又是多次从磁盘中读取数据的话,那么数据库管理员就要注意了。因为从磁盘中读取数据要比从内存中读取数据慢的多。此时,若数据库管理员能够想方设法,让这些执行频率高的SQL语句不直接从磁盘中读取数据,而是从内存中读取数据,那么就可以非常有效的提高SQL语句的执行效率。
另外数据库可以员也可以通过Statspack方法来定位SQL语句。当我们启用这个功能的时候,数据库会生成一张Stats$Sql_summary的表。他的功能跟上面这张表类似,只是他会有选择的纪录相关的信息。
在Sql_Parameter会记入相关的条件。如当SQL语句执行次数大于多少才进行纪录;又或者当SQL语句执行磁盘读取次数大于多少时进行统计等等。通过这个过滤,会让数据库管理员了解更多的信息。但是,这里要注意一个问题,当任何一个指标超出(Oracle官方资料上把这个指标叫做阀值)的时候,系统就会往上面这个表中添加一条纪录。所以如果这个指标设置的比较低,当数据库比较繁忙的时候,我们会发现这张表会变得非常的活跃。数据库会时不时的向这张表中添加纪录。
所以,如果数据库管理员想用这种方法来定位SQL语句的话,那么需要同时做好两项工作。
一是需要根据SQL调整过程来随时调整这个指标。当我们数据库管理员需要对SQL语句进行调整的时候,就必须要降低指标值。如此才能够定位那些不常用的SQL语句,并对其进行调整。但是,降低指标值会导致数据库向这个表中添加更多的纪录。此时,数据库管理员在调整过后,就要手工删除这表中多余的数据。
二是要定期的查看这表中的内容。因为随着系统应用时机的不同,有些SQL语句可能在某个时段后不再使用。所以,如果SQL调整不再使用这些内容的话,则数据库管理员从这张表中删除他们就显得非常的必要了。
二、使用第三方工具对其进行定位。
除了Oracle数据库自带的工具之外,我们数据库管理员还可以利用一些第三方的工具或者脚本来对常用的SQL语句进行定位。
如有些公司开发了一些GUI工具。这些工具可以帮助我们数据库管理员迅速显示程序库缓存中的SQL 语句,并且通过一些参数,还可以抽取执行频率比较高的或者耗用资源比较多的SQL语句。另外,我们也可以自己写一些SQL脚本。通过这个脚本来直接读取数据库缓存中的SQL语句。
采用第三方工具有时候会比上面这个方法更加的有用。因为上面这个方法其纪录的是一个过去式的结果。而直接在缓存中读取的数据,则反映的是及时的数据。如当用户发觉数据库性能降低的时候,则数据库管理员可以采用这些工具,了解SQL语句的执行情况,看看是否是因为SQL语句所造成的。
当数据库管理员找到影响数据库性能的那个SQL语句之后,我们就可以对每个可疑的SQL语句进行调整。
如数据库管理员可以更改优化器模式。在Oracle数据库中,提供了不少的优化器模式,如最快优化器或者耗用资源最少优化器等等。数据库管理员可以尝试更改不同的优化器模式,然后让数据库产生多个执行计划。通过对每个计划进行追踪、分析、计时,来确定那个执行计划具有最快的执行时间。
如可以添加提示,来强制改变执行计划,来获得最优的执行时间。调整SQL语句的过程包含多个操作。SQL语句的调整从全局水平转移到特定的水平。SQL语句调整的终极目标是缩短SQL语句的执行时间。Oracle数据库中不同的执行计划,其执行所需要的时间是不同的。出于调整的需要,数据库管理员可以通过向所选择的语句中添加提示的方式,强制对执行计划进行修改。
如可以通过添加索引来删除不必要的全表扫描。索引是提高数据库查询性能的一个法宝。当SQL语句查询效率低下,数据库管理员想到的第一个方法就是能否对表添加合适的索引来提高SQL语句的查询效率。通过对表添加索引,特别是基于位图和基于函数的索引, 可以防止一些不必要的全表扫描。不过,在后续调整的过程中给表添加索引的话,要注意一个问题。就是添加索引后,可能会造成许多其他的SQL语句执行计划的改变。所以,在为某一个SQL语句调整添加或者删除了某个索引之后,可能会发现其他的SQL语句执行效率有所改变。故一般在后期的SQL语句调整过程中,我们都不怎么建议数据库管理员对原来的索引进行调整。在确实有必要的情况下,数据库管理员要能够站在一个全局的角度,去评估索引更改后对其他SQL语句执行计划的影响。从而最终确定这么处理是否合适。
另外在对单独的SQL语句进行调整的时候,还需要注意一个持久化的问题。也就是说,对SQL语句的调整,无论是执行计划的调整,还是优化器模式的改变,其效果不能够只是暂时的。让SQL语句调整变得更持久,只有如此,调整才有实际意义。
如何才能够提高调整后的SQL语句的持久性呢?笔者这里有一个小的建议。如果通过以上的定位方法,了解到某条SQL语句执行频率非常高,或者耗用的资源比较多,又或者多次从磁盘中读取数据。对于这种SQL语句,如何保证调整的持久化呢?此时,可以改变SQL语句的来源来达到持久化的目的。如当数据库管理员发现SQL语句是来源于应用程序。此时,在调整的过程中,数据库管理员可以考虑,把应用程序传递过来的SQL语句打包放入存储过程,然后把存储过过程放入Oracle系统的软件包中来实现。他可以让我们定。位SQL语句的工作来的简单;而且,他还使得所有远程 的应用程序更加便于移植,因为对Oracle的调用都是封装在数据库函数或者过程之中。
从以上的分析中我们可以看出,要对SQL语句进行调整,无论是采取何种方式,第一件工作就是要定位需要对哪些SQL语句进行调整。为了提高调整的效果,哪些执行频率高、耗用资源多的SQL语句,就成为我们调整的对象。所以,如何定位这些语句就显得至关重要。我们只要找到这些SQL语句,就可以使得我们的优化工作事半功倍。
3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.com/exam/