·建站首页 ·钻石 ·繁體
您的位置: 中国建站之家 -> 网站开发设计 -> 数据库开发 -> 探讨SQL语句技巧 优化DB2应用程序性能

探讨SQL语句技巧 优化DB2应用程序性能

作者:恒东辉  来源:本站整理  发布时间:2007-10-16 11:41:06  发布人:圈圈

本文以IBM的关系数据库管理系统DB2 Universal Database(通用数据库) 版本7.1为背景,与大家共同探讨编写好的SQL语句的技巧,以求DB2应用程序以求DB2应用程序获得更优的性能。

  当我们设计一个新的或分析一个现存的系统时,其中所要考虑的一个重要问题就是应用程序的设计问题。即使数据库设计得很好而且还经过优化处理,应用程序设计不适当还是会引起性能问题的 数据库。实践证明,如果应用程序存在设计上的问题,那么修改这些问题比调整数据库配置参数更能改善应用程序的性能。

  例如,SQL是一种高级语言,具有很大的灵活性,从数据库中提取相同的数据可以用不同形式的SELECT语句来实现,但是,应用程序的性能却随着SELECT语句形式的不同而大相径庭,这是因为不同形式的SELECT语句具有不同的处理成本。在这种情况下,我们就应该选择那些处理成本低廉的SELECT语句,这样,应用程序才会有较好的性能。

  DB2通用数据库本身提供一个SQL编译器,该编译器创建编译后的SQL语句,当该编译器编译SQL语句时,它将重新编写这些SQL语句,以生成一种更容易对其进行优化的形式,这个过程称之为“查询重写(query rewrite)”。

  然后,SQL编译器产生许多满足用户查询要求的、可选的执行方案,并根据表、索引、列和函数的统计数字来评估每个方案的执行成本,最后,从中选取执行成本最低的方案,该过程称之为“查询优化(query optimization)”。

  有一点很重要,需要我们注意,那就是不管存取方案的优劣,SQL编译器(包括查询重写和优化两个阶段)必须从中选择一个,以产生满足应用程序查询要求的结果集,因此,我们在编写查询代码时,只应查询我们需要的数据,不需要的数据就不要查询,这样做的目的是确保SQL编译器能够选择一个最好的存取方案。

  编写SELECT语句时一般遵循以下七个方面的准则:

  1、在SELECT列表中仅仅指明需要的列

  我们在编写SELECT语句时,尽管有时候不需要用到表中所有的字段,但还是习惯用*(表示引用表中所有的字段)来指定表中所有的列,这样做在编程上确实很简单、方便,但这么做的后果是应用程序返回一些我们不需要的列,系统做一些不必要的处理,做一些无用功,徒耗系统宝贵的软、硬件资源,尤其当表中有很多字段时,这种浪费现象就越加明显;而且,这也不是良好的编程习惯,我们不应提倡。

  2、使用谓词来限制返回的行数

  在SQL编程语言中,按照评估过程中如何使用谓词、何时使用谓词,我们将谓词划分为四大类(这四类谓词各自有不同的处理成本),按性能由高至低排列如下:

  • 范围界定谓词
  • 索引参数谓词
  • 数据参数谓词
  • 剩余谓词

  范围界定谓词是指那些限定索引扫描范围的谓词,它们为索引搜索提供键值的起始值和/或终止值。索引参数谓词不用于界定搜索范围,但可以根据索引对它进行评估,因为谓词中的列是索引中的一部分。例如,假设表staff中的索引定义在name,dept和years三个字段上,执行下面的SELECT语句:

  SELECT name,job,salary FROM staff
  WHERE name=’John’
  dept=10
  years>5

  头两个谓词(name=’John’和dept=10)是范围界定谓词,而years>5是索引参数谓词,因为单凭上述信息我们无法确定键years的起始值是多少,起始值可以是6,8,10,甚至更大。如果years的谓词是years>=5,那么,它就是范围界定谓词了,因为索引搜索可以从5开始。

  数据库管理器在评估这些谓词的时候将利用索引数据,而不是读取数据库中的基本表。这些范围界定谓词和索引参数谓词通过减少需要从表中读取的行的数目来减少存取的数据页的数目。索引参数谓词不影响被存取的索引页的数目。

  数据参数谓词是那些不能被索引管理器评估,却能被数据管理服务(DMS)评估的谓词。通常,这种谓词需要从基本表中存取个别行,如果需要的话,数据管理服务还会提取需要的列来评估该谓词。

  例如,假设索引定义在表project的projno列上,而不是deptno列上,执行下面的查询:

  SELECT projno,projname,repemp FROM project
  WHERE deptno=’D11’
  ORDER BY projno

  谓词“deptno=’D11’”是数据参数谓词,因为没有索引定义在deptno列上,必须存取基本表来评估该谓词。

  剩余谓词是指那些除了对基本表进行简单的存取操作之外,还要进行I/O操作的谓词,包括使用子查询的谓词(子查询中带有ANY,ALL,IN或SOME),以及读取LONG VARCHAR或大对象(LOB)数据的谓词(在DB2中,LONG VARCHAR、大对象和表是分开存放的)。

  剩余谓词是用关系数据服务(RDS)来进行评估的,而且,它在这四类谓词中成本最昂贵。由于相对范围界定谓词和索引参数谓词来说,剩余谓词和数据参数谓词的成本比较高,所以,我们应该尽可能地限制范围界定谓词和索引参数谓词界定的行数。

  我们来看一下DB2的组件:索引管理器,数据管理服务和关系数据服务。图1显示DB2的各个组件和处理这四类谓词的位置。

  

  图1 DB2 UDB组件和谓词

  其实,DB2组件很多,图1只是一个简化后的示意图。

  关系数据服务(RDS)从应用程序那里接收到SQL请求,并返回结果集;除了剩余谓词外,RDS将所有谓词都发送给数据管理服务(DMS);剩余谓词由RDS进行评估。

  DMS评估数据参数谓词。如果SELECT列表中存在一些不能由索引搜索进行评估的列,那么,DMS就会直接扫描数据页。

  索引管理器从DMS那里接收、评估范围界定谓词和索引参数谓词,然后,将数据页的行标识符(RID)返回给DMS。

  了解各种谓词的定义、转换条件及其使用场所,对我们深入剖析应用程序,提高应用程序性能是有所裨益的。

  3、指定FOR UPDATE子句

  如果想更新提取的数据,我们应该在游标定义的SELECT语句中指定FOR UPDATE子句。这样做的好处在于,数据库管理器在开始的时候就可以选择适当的加锁级别,例如,使用U(更新)锁,而不是S(共享)锁,这样,当处理后续的UPDATE语句时,就可以省去从S锁转换到U锁的开销了。

  指定FOR UPDATE子句的另外一个好处是可以减少应用程序的死锁机会。死锁是这样一种情形:一个以上的应用程序等待另外一个应用程序释放对数据的锁定,而那些等待的应用程序正占据着另外应用程序所需要的数据,并且对该数据也进行了锁定。我们假设两个应

[1] [2]  下一页

将本文收藏到QQ书签与更多好友分享