摘要: 如果所处理的数据会一直保留在应用的逻辑工作单元中,可以考虑使用全局临时表(global temporary table,GTT),而不要反复建立或物化数据。如果在程序执行期间多次获取或物化同样的数据,可以把这些数据在一个GTT中加载一次,然后在代码的其他地方引用这个表。例如,一个程序有多个游标,每个游标包含多个表联接。另外,每个游标都包含同样的表Table1,而这恰好是各个查询的驱动表。处理各个游标时,可能必须从数据库获取相同的行来完成Table1处理。这样一来,就会导致对相同数据额外的I/O处理。所以,更好的做法是先获取Table1数据,把它插入到一个GTT中,然后在各个游标中引用这个GTT 阅读全文
posted @ 2013-07-12 09:24 小土_ 阅读(234) 评论(0) 推荐(0) 编辑
摘要: 假设一个查询性能不佳,它的主要筛选谓词之一是一个区间谓词,如下所示:WHEREHIREDATE>:HV-DATE如果数据库管理器没有使用HIREDATE列上的索引,你可能希望尽量让它使用这个索引,那么可以如下编写代码:WHEREHIREDATEBETWEEN:HV-DATEand:HV-DATE2只是要确保将第二个变量设置为某个极值,并将其包含在一个宿主变量字段中(这里设置为 ‘9999-12-31’)。注意,只有在使用宿主变量(静态SQL中)或参数标记(动态SQL)时这种方法才奏效。优化工具很聪明,它知道实际上硬编码的 ‘9999-12-31’不会改变逻辑。不过,如果它看到一个变量,在 阅读全文
posted @ 2013-07-12 09:20 小土_ 阅读(300) 评论(0) 推荐(0) 编辑
摘要: 性能调优中通常都要尽量减少对DB2的SQL请求,特别是批量程序,因为与其他程序相比,批量程序会处理更多的数据。每次向数据库管理器发送一个SQL调用都会带来开销,包括向DB2发送SQL语句的开销,以及从操作系统的一个地址空间到另一个地址空间以便DB2执行的开销。所以,一般来讲开发人员需要尽量减少:打开/关闭时间游标的次数。随机的SQL请求数(在DB2监视器中称为同步读)。很多开发人员会采用过程方式考虑和编写代码。利用RDBMS开发应用并编写SQL时,开发人员需要更多地从关系角度来考虑。也就是说,他们需要考虑“怎样才能向数据库管理器发送最少的SQL语句来得到所需的全部数据,而不是做这么多的过程调用 阅读全文
posted @ 2013-07-12 09:19 小土_ 阅读(224) 评论(0) 推荐(0) 编辑
摘要: 大多数开发人员会在需要时写UNION,这往往会导致执行一个排序来消除重复。不过,不同的查询之间通常并不存在重复,所以SQL语句应该写为UNION ALL,从而去除这种“做无用功”的排序。例如:SELECTDEPTNO FROMDEPT WHEREMGRNOin('000010','000020','000030') UNION SELECTDEPTNO FROMPROJ WHEREPROJNO='PA1000'如果有UNION语句,DB2最后会自动地执行一个排序来消除所有DEPTNO重复。不过,有很多这样的查询,在不同的查询之间可 阅读全文
posted @ 2013-07-12 09:17 小土_ 阅读(924) 评论(0) 推荐(0) 编辑
摘要: 要使用硬编码而不是使用宿主变量,如果程序员在SQL语句中使用了宿主变量字段,这一点就尤其重要。大多数COBOL程序都写为静态SQL程序而不是动态SQL程序。对于这些COBOL程序,执行DB2 Bind时,直至运行时之前优化工具都无法知道宿主变量中的具体值。所以,优化工具为SQL语句选择访问路径时,它会有一些默认的判定规则。例如,假设一个表包含100万行。在这个表中,列Status_Cd上有一个索引。对这个表执行典型的Runstats时,优化工具会知道状态码(Status_Cd)有3个不同的值。运行一次特殊的Runstats之后,会为这个列指定频率值统计信息,DB2就会了解到以下数据分布:状态码 阅读全文
posted @ 2013-07-12 09:17 小土_ 阅读(278) 评论(0) 推荐(0) 编辑
摘要: 可以在各个指定表和关联索引上执行Runstats工具,这样就能确保所处理的表的数据分布和其他统计信息正确并且反映当前的最新状况。这个工具会在系统编目表中加载某个表和/或关联索引特性的有关信息。另外它还会提供数据分布信息,优化工具在选择访问路径时会查找这些信息。下面是Runstats工具提供的部分信息:表大小(行数)索引列的基数某些列按值统计的行频率信息表文件的物理特性分区表按分区统计的信息如果没有加载表统计信息,或者表统计信息已经过时,优化工具可能会选择并不特别适用于这些表的访问路径。这可能会影响性能。例如,如果一个表包含500万行,但Runstats是在表包含20万行时运行的,那么DB2仍然 阅读全文
posted @ 2013-07-12 09:16 小土_ 阅读(231) 评论(0) 推荐(0) 编辑
摘要: 尽可能分离谓词。下面的例子可以说明这一点:SELECTDEPTNO,DEPTNAME FROMDEPT WHERE(ADMRDEPT='E01'ANDDEPTNAMELIKE'BRANCH%') OR(DEPTNO='D01'ANDDEPTNAMELIKE'BRANCH%')也可以写作:SELECTDEPTNO,DEPTNAME FROMDEPT WHERE(ADMRDEPT='E01'OR DEPTNO='D01') ANDDEPTNAMELIKE'BRANCH%'这里的关键是:可 阅读全文
posted @ 2013-07-12 09:15 小土_ 阅读(229) 评论(0) 推荐(0) 编辑
摘要: 如果一个列定义为一个小整数,那么与它比较的宿主变量也应当声明为相同的定义(例如COBOL中声明为S9(4) comp)。这在DB2 V8和V9中已经有显著改进,在这两个版本中,DB2会更高效地处理进行比较的不同数值数据类型和不同字符串。DB2中可定义的数据类型并非在所有开发语言中都可用,在过去这会带来一些问题。不过从一般经验来看,将数据类型声明为与列定义匹配,可以确保最高的性能和最大程度的优化。例如,如果一个列定义为整数数据类型,那么谓词中包含比较值的宿主变量也应该定义为整数(而不是小整数、小数、浮点数,等等)。COBOL程序员应当尽可能利用已创建的DCLGEN宿主变量来确保完全匹配。DCLG 阅读全文
posted @ 2013-07-12 09:14 小土_ 阅读(268) 评论(0) 推荐(0) 编辑
摘要: In和Exists子查询可以生成同样的结果,不过它们的做法截然不同。通常它们的表现各有优劣,这取决于实际的数据分布。例如:SELECTE.EMPNO,E.LASTNAME FROMEMPE WHEREE.EMPNOIN (SELECTD.MGRNO FROMDEPARTMENTD WHERED.DEPTNOLIKE'D%')也可以写为:SELECTE.EMPNO,E.LASTNAME FROMEMPE WHEREEXISTS (SELECT1 FROMDEPARTMENTD WHERED.MGRNO=E.EMPNO ANDD.DEPTNOLIKE'D%')这些相 阅读全文
posted @ 2013-07-12 09:13 小土_ 阅读(457) 评论(0) 推荐(0) 编辑
摘要: 大多数情况下,Distinct函数都会导致对最终结果集完成一次排序,因此,这就成为成本最昂贵的排序之一。Distinct一直是SQL语言中成本最高的函数之一。不过,对于DB2 V9,优化工具会尽量利用索引来消除为确定唯一性所带来的排序,其方法类似于目前用Group By语句完成优化时的做法。不过,实际上不必在SQL中使用Distinct,完全可以使用其他方式重写查询来得到同样的结果,这样做往往更为高效。开发人员现在都很喜欢用Distinct,很多人在所有语句上都会加上Distinct来确保不出现重复。不过这种代码的效率很低。在对应用调优时,我首先要做的事情之一就是审查源代码,找出所有包含Dis 阅读全文
posted @ 2013-07-12 09:12 小土_ 阅读(300) 评论(0) 推荐(0) 编辑
摘要: 如果Select部分包含不需要的列,优化工具会选择Indexonly = ‘N’,这会强制DB2必须进入数据页来得到所请求的特定列,这就要求更多的I/O操作。另外,由于这些多余的列可能是某些排序的一部分,这样一来,就需要创建和传递一个更大的排序文件,相应地会使排序的成本更高。对于排序来讲,其规模大小会直接影响成本。随着排序规模变大,成本也会更昂贵。如果查询中涉及多个表,指定多余的列还会对优化工具选择何种联接类型产生影响。目前,z/OSDB2中有4种联接类型(嵌套循环联接、合并扫描联接、复合联接和星型联接),DB2 LUW中还有一种哈希联接。优化工具会根据不同的原因选择各种联接类型。如果包含了根 阅读全文
posted @ 2013-07-12 09:11 小土_ 阅读(308) 评论(0) 推荐(0) 编辑
摘要: 肯定有办法重写谓词,使得谓词列上不再使用数学运算。在SQL语句的Select部分对列应用数学运算是完全可以的,不过如果在Where部分中对列使用数学运算,就会自动将谓词变成不可索引的谓词。例如:SELECTEMPNO,LASTNAME FROMEMP WHERESALARY*1.1>50000.00应当写为:SELECTEMPNO,LASTNAME FROMEMP WHERESALARY>50000.00/1.1如上所示重写这个SQL语句之后,DB2可以选择使用列SALARY上的索引(如果存在这样一个索引)。但是如果这个语句编写为直接对SALARY列应用数学运算, DB2就无法使用 阅读全文
posted @ 2013-07-12 09:09 小土_ 阅读(149) 评论(0) 推荐(0) 编辑
摘要: 开发人员编写SQL代码时,为了确保得到更好的性能,需要采取一些措施,下面会列出其中最有效的一些做法。在关系型数据库管理系统(relational database management system,RDBMS)中,通常90%的运行时问题源于10%的应用问题。与以往相比,如今的DB2优化工具在选择正确的访问路径来满足SQL需求方面已经更胜一筹,不过仍不能保证百分之百正确。目前的所有调优工作都与CPU使用、I/O和并发直接关联。本章的大部分内容都会针对SQL编码,不过所有内容都与性能和调优有关。本书中给出的技巧和提示是为开发人员提供的一般最佳实践,适用于大多数RDBMS。在这些数据库系统中,可能 阅读全文
posted @ 2013-07-12 09:07 小土_ 阅读(201) 评论(0) 推荐(0) 编辑