在 前一期 IBM Database Magazine 中,本专栏的第 1 部分从系统和数据库的角度讨论了 IBM DB2 数据仓库性能管理。在本期中,我将针对 SQL 语句级性能调优提供一些建议。
在进行查询调优时,不但要追求良好的性能,还要确保做正确的事。您很可能希望先调整长时间运行的查询,但是这些查询不一定是 “问题” 查询。如果一个查询会频繁地执行,而且用户期望包含它的过程在一两秒内完成,那么即使它的运行时间只有 10 秒,也会引起用户的抱怨。
对于判断什么地方最需要调优,最好的依据往往是 “用户的声音”。如果用户没有什么抱怨,那么可以花时间调整那些运行时间(和/或 CPU 时间)长和执行频率高的查询。
市场上有一些工具可以帮助选择查询调优目标(IBM 提供的产品包括 DB2 Query Monitor for z/OS 和 DB2 Performance Expert for Linux, UNIX, and Windows)。但是,可以从 DB2 本身获得有助于选择查询调优目标的信息。大型机管理员应该使用 EXPLAIN 语句的 STMTCACHE ALL 选项(这是在 DB2 for z/OS V9 中引入的,对于 V8 通过 APAR PQ88073 补丁提供)。对于动态语句缓存中的每个 SQL 语句,EXPLAIN STMTCACHE ALL 会在 DSN_STATEMENT_CACHE_TABLE 中插入一行。在 DSN_STATEMENT_CACHE_TABLE 中的 40 多列中,记录了查询的语句文本、累积的流逝时间、累积的 CPU 时间和执行次数等信息。这些信息应该有助于寻找可能产生良好的性能调优效果的语句。
在 Linux、UNIX 和 Windows (LUW) 上,DB2 管理员可以使用 DB2 9 引入的管理视图(这些视图的高层限定词是 SYSIBMADM;可以通过 DB2 9 for LUW System Monitoring Guide and Reference 了解这些视图)。其中特别有用的一个视图是 SYSIBMADM.TOP_DYNAMIC_SQL,它包含 STMT_TEXT、AVERAGE_EXECUTION_TIME_S 和 NUM_EXECUTIONS 列。
语句级调优通常需要为访问生成查询结果集所需的数据找到更好的方法。要完整地扫描整个表吗?要使用索引吗?如果要联结表,应该使用哪种联结方法?回答这些问题就会确定查询的访问路径;调优的目标是找到更好的路径,减少语句的执行时间。
但是,首先需要了解 DB2 优化器选择的路径。可以通过 DB2 EXPLAIN 语句获得这一信息(可以通过查询 EXPLAIN 表以文本形式查看语句的 EXPLAIN 输出,也可以使用 Optimization Service Center for DB2 for z/OS 或 DB2 for LUW 的 Visual Explain 功能以图形形式查看这一信息)。得到 EXPLAIN 输出之后,查看查询的结果集是如何生成的,然后考虑是否可以采用其他访问路径。
为了正确地评估这些访问路径,需要从 DB2 编目中获取关于查询访问的表以及这些表上定义的索引的信息。请记住,优化器使用编目数据决定访问路径。如果编目统计数据不准确,应该使用 RUNSTATS 更新它们。这个简单的步骤可能产生新的访问路径,可能显著改进查询性能。
在查看 DB2 为目标查询选择的访问路径时,问自己一个问题:DB2 应该为这个查询选择不同的访问路径吗?如果您觉得另一个路径更好,那么考虑查询访问的表(及其相关联的索引)是否组织良好。如果编目统计数据是最新的,而 DB2 知道某个索引组织得不好,DB2 就可能决定不使用它。在这种情况下,重新组织索引可能会影响 DB2 的选择,可能产生性能更好的查询访问路径。
您和 DB2 选择的访问路径之所以有差异,可能的原因之一是您了解 DB2 不了解的某些信息。例如,您知道某个列中的数据值不是均匀分布的。如果编目中没有列数据值分布信息,DB2 就会假设值是均匀分布的,这可能导致优化器选择非最优的访问路径。
如果查询谓词中引用的列存在显著的数据值倾斜,那么要确保 DB2 了解这一情况,最好是使用 RUNSTATS 生成列值柱状图统计数据。在 DB2 for LUW 中早就可用的柱状图统计数据可以由 DB2 for z/OS V9 中的 RUNSTATS 生成。如果使用 DB2 for z/OS V8,可以使用 RUNSTATS 的 FREQVAL 选项)。注意,可以通过 Optimization Service Center for DB2 for z/OS 获得改进 DB2 for z/OS 编目统计数据的建议,从而改进查询(可以从 IBM.com 下载免费版本)。
如果您和 DB2 认为的最佳可用访问路径是一致的,但是这个路径不能提供让人满意的性能,那么需要向 DB2 提供新的访问路径选择。有几种方法,包括调整索引、使用物化查询表和表重聚簇。
与索引相关的操作可以减少 DB2 在生成查询结果集时必须检查的页面数量。可以在谓词引用的列上定义索引(如果还没有定义的话)。对于已经定义了索引的一组列,可以以不同的列次序定义新索引,从而增加 DB2 在执行与谓词相关的值匹配时使用的索引键列数量。(例如,对于复合谓词 COL_A > y AND COL_B = x,假设在 COL_A | COL_B 上已经有索引,那么可以在 COL_B | COL_A 上创建新索引,这让 DB2 可以匹配两个索引键列,而不是只匹配第一个键列)。可以在现有的索引中添加列,让查询处理的一部分只访问索引。
为查询提供更好的访问路径的另一种方法是使用 DB2 的物化查询表 (MQT) 功能。MQT 是通过 SELECT 语句定义的(通常是一个结果集),这样就不需要在执行查询时动态地构建这个结果集。MQT 有三个优点:
- DB2 可以自动地重写查询以使用 MQT。
- 因为 MQT 中的结果集已经建立了,经过 DB2 重写访问这个 MQT 的查询不必在查询执行时花时间动态地构建结果集,这会显著降低运行时间。
- 可以在 MQT 上定义索引,这会进一步提高查询性能。表重聚簇是向 DB2 提供更好的访问路径的另一种方法,这会减少 DB2 在执行查询时必须检查的页面数量。数据聚簇对于数据仓库查询性能的影响尤其显著,因为常常在一个查询中获取许多行。如果表原来按账号列聚簇,但是后来发现用户常常按日期范围从表中获取行,就可以考虑改变表的聚簇次序,让获取的行在表中的位置相互接近。另外,如果联结的表都按联结列的次序聚簇,联结操作的性能也可能显著提高(例如,当联结谓词是 TABLE_A.CUSTOMER_ID = TABLE_B.CUSTOMER_ID 时,按 CUSTOMER_ID 聚簇)。
一定要记住,如果决定对表进行重聚簇,在 DB2 for z/OS V9 上可以通过 ALTER INDEX 语句的新选项 CLUSTER 和 NOT CLUSTER 大大简化这一操作。如果对表进行重聚簇,一定要考虑利用最近几个 DB2 版本中提供的与聚簇相关的改进,比如 DB2 for LUW 中的多维聚簇,以及在 DB2 for z/OS 环境中按一个键进行表分区,在分区内按另一个键聚簇的功能。
希望您的数据仓库查询调优取得良好的效果。业务智能化是近来的热门领域,有助于利用各种机会为您的组织提供真正的价值。
学习
- 通过访问 developerWorks 中国 Information Management 专区的 DB2 9 技术资源中心 获得更多 DB2 9 相关的文章、教程和多媒体课件等学习资源。
- 通过访问
DB2 V9.7 信息中心 ,了解 DB2 V9.7 的基本概述。
- 通过访问 Data Warehousing 产品专题,了解 Data Warehousing 相关的产品和文档、教程等技术资源。
获得产品和技术
- 现在可以免费使用 DB2 。下载 DB2 Express-C,这是为社区提供的 DB2 Express Edition 的免费版本,它提供了与 DB2 Express Edition 相同的核心数据特性,为构建和部署应用程序奠定了坚实的基础。
- 下载 IM 软件试用版,体验信息管理软件强大的功能。
讨论
- 通过访问 alphaWorks 获得更多 IBM 的前瞻性技术和资源。
- 通过访问 IBM Database Magazine 站点 community 专题 获得更多用户体验和交流信息。
Robert Catterall 是位于亚特兰大的 CheckFree 公司的工程主管。Email:rcatterall@checkfree.com