DB2 最佳实践: 编写并调优查询语句以优化性能最佳实践

内容提要 算法

经过 “IBM DB2 for Linux, UNIX, and Windows 最佳实践”专题,得到最经常使用的 DB2 9 产品配置实践指南,并使用这些知识提升 DB2 数据服务器的价值。 数据库

这些最佳实践文章给出了最优化方法的建议,使您能使用 DB2 知足关键的业务数据处理需求。每篇最佳实践文章都为最经常使用的 DB2 产品配置提供了实践指南。经过应用这些建议,您能够提升 DB2 数据服务器的价值,而且可以始终把握 IBM 在 DB2 方面的技术方向。 编程

本文描述了在 DB2 数据库性能方面最小化 SQL 语句的影响的最佳实践。有几种将影响减到最小的方法: 缓存

  • 经过编写能够很容易被 DB2 优化器优化的语句。 DB2 优化器能够高效的运行不包含链接谓词的 SQL 语句、链接列数据类型不匹配、多余的外链接和其余复杂搜索条件。
  • 经过改正配置 DB2 数据库将从 DB2 优化功能获得好处。若是你有精确的编目统计信息并为你的工做负载选择了最好的优化级别 DB2 优化器能够选择最优的查询计划。
  • 经过使用 DB2 explain 功能来查看可能的插叙计划并判断如何调整查询以达到最佳性能。

本文包括最佳实践对适用于、通常的工做负载、数据仓库工做负载和 SAP 工做负载,包括特定 SAP 商业智能(BI)应用程序。 性能优化

这里有不少方法来处理应用程序编写后特定的查询性能问题。可是,本文专一于良好的基础编写和调优练习,这能更普遍的提升 DB2 数据库性能。 服务器

若是你遵循了本文讨论的建议后仍然碰到性能低下的问题,这也有不少技术可让你理解为何会性能低下。“性能调优和问题诊断最佳实践” 最佳实践文章描述了不少技术来定位性能问题和进行系统配置来防止它们。“物理数据库设计最佳实践”最佳实践文章中描述了如何使用 DB2 数据库系统功能,想多位集群(MDC),物化查询表(MQTs)和 DB2 Design Advisor 来达到优化查询性能的目的。后面的最佳实践文章将描述分析特定查询性能问题的技术。 数据结构

对于提升 XQuery 性能的建议,参见“使用 DB2 pureXML 管理 XML 数据的最佳实践”数据库设计

回页首 函数

介绍 工具

查询性能不能只考虑某一次的问题,而应该贯穿于应用程序开发的整个生命周期,在设计、开发、生产各个阶段中都要考虑它。

SQL 是一个很是灵活的语言,也就是说有不少途径一样能够得到正确的结果。这种灵活性也意味着利用 DB2 优化器具备优点,一些查询会优于其余的查询。

在查询运行的过程当中,DB2 优化器会为每一个 SQL 语句选择一个查询计划。优化器模拟不一样的访问计划的运行成本,并选择其中一个成本最低的访问计划。若是一个查询包括不少复杂的搜索条件,DB2 优化器在某些状况下能够重写谓词,不过在某些一些状况下却不能。

对于一些比较复杂的查询,一个 SQL 语句的准备或编译的时间可能会比较长,尤为是 BI 应用程序中使用的 SQL 语句。你能够经过调整设计和你的数据库配置来帮助缩短语句编辑时间。这包括选择正确的优化级别并正确设置其余注册变量。

优化器也须要精确输入以得到精确的查询计划。这意味着你须要收集精确的统计信息,并潜在的使用高级统计功能,好比统计视图和列组统计信息。

你也可使用 DB2 工具(尤为是 DB2 explain 工具)来调优查询。 DB2 编译器能够抓取动态或静态语句关于访问计划和环境的信息。利用抓取的信息来理解单个语句的运行,因此你能够调整它们以及你的数据库管理器配置来提升性能。

回页首

编写 SQL 语句

SQL 是很强大的语言,它容许你指定语法不一样而语义相同的关系型描述。不过,一些语义相同的变化比起其余的更容易优化。虽然 DB2 优化器有很强的查询重写能力,但也并不老是能够把一个 SQL 语句重写成最优的形式。某些 SQL 结构也可能会限制优化器对访问计划考虑。下面的章节描述了须要避免的某些 SQL 结构,并对如何替换或避免它们提出了建议。

在搜索条件中避免复杂的描述

在搜索条件中避免复杂的描述,这样的描述阻止了优化器使用编目统计信息来评估一个精确的选择。这个描述也可能会限制选择能够应用这些谓词的访问计划。在优化的查询语句的重写阶段,优化器能够重写一批描述以容许优化器评估一个精确的选择;不过它不能处理全部可能性。

在描述中避免使用链接谓词

在描述中使用链接谓词把链接方法限制为了嵌套循环。另外,对基数的评估可能不许确。下面是一些链接描述的例子:

WHERE SALES.PRICE * SALES.DISCOUNT = TRANS.FINAL_PRICE 
 WHERE UPPER(CUST.LASTNAME) = TRANS.NAME

避免对本地谓词有过多的列描述

使用相反的描述来替代应用中的一个在本地谓词上有太多列的描述。考虑下面的例子:

XPRESSN(C) = 'constant' 
 INTEGER(TRANS_DATE)/100 = 200802

你可把它们语句重写为:

C = INVERSEXPRESSN('constant') 
 TRANS_DATE BETWEEN 20080201 AND 20080229

应用多列的描述将妨碍索引开始和结束键的使用,从而致使不许确的可选评估,并须要在查询运行时花费额外的时间来处理。这些描述一样会阻止对查询的重写优化,好比在列相等时的识别、使用常量来替换各列而且对只有一行返回的状况进行识别。在这以后的进一步的优化也可能会被阻止,所以会失去更多的优化机会。考虑下面的查询:

SELECT LASTNAME, CUST_ID, CUST_CODE FROM CUST 
 WHERE (CUST_ID * 100) + INT(CUST_CODE) = 123456 ORDER BY 1,2,3

你也能够用下面的语句:

SELECT LASTNAME, CUST_ID, CUST_CODE FROM CUST 
 WHERE CUST_ID = 1234 AND CUST_CODE = '56' ORDER BY 1,2,3

若是在 CUST_ID 上有一个惟一索引,重写的查询版本让查询优化器注意到最多一行记录将被返回。这避免了引入一个没有必要的排序操做。这也让 CUST_ID 和 CUST_CODE 列被 1234 和‘ 56 ’替代,从而避免了从数据页或索引页复制数据。最终,使得在 CUST_ID 上的谓词应用成一个索引开始或结束键。

当一个描述在谓词中时,它可能不是总这么明显。这种状况常常发生在涉及视图的查询中,尤为当视图列是经过描述定义的时候。好比,考虑下面视图定义和查询:

CREATE VIEW CUST_V AS 
 (SELECT LASTNAME, (CUST_ID * 100) + INT(CUST_CODE) AS CUST_KEY FROM CUST) 
 SELECT LASTNAME FROM CUST_V WHERE CUST_KEY = 123456

查询优化器把查询和视图定义合并了,产生下面的查询:

这是前面例子中有问题的谓词。你能够经过使用 explain 功能显示优化后的 SQL 语句来观察视图合并的结果。

若是相反的功能很难表达,考虑使用一个生成列。例如,若是你想找到一个知足 LASTNAME IN ('Woo', 'woo', 'WOO', 'WOo', and so on) 描述标准的姓氏,你能够建立一个生成列 UCASE(LASTNAME) = 'WOO' ,以下 :

CREATE TABLE CUSTOMER 
 (LASTNAME VARCHAR(100), 
 U_LASTNAME VARCHAR(100) GENERATED ALWAYS AS (UCASE(LASTNAME))) 
 CREATE INDEX CUST_U_LASTNAME ON CUSTOMER(U_LASTNAME)

避免链接列上的数据类型不匹配

在某些状况下,数据类型不匹配将妨碍使用哈希链接。哈希链接在链接谓词上比其余链接方法要多一些约束。特别是链接列的数据类型必须彻底相同。例如,若是一个链接列是 FLOAT 另一个是 REAL,哈希链接将不支持。另外,若是链接列数据类型是 CHAR、GRAPHIC、DECIMAL 或 DECFLOAT 则长度必须同样。

在谓词中不要使用 no-op 描述来更改优化器评估

一个“ no-op ” coalesce() 谓词以“ COALESCE(X, X) = X ”会引入一个评估错误到使用它的全部查询的计划中。如今 DB2 查询编译器没有能力不去选则那个谓词并肯定是否全部的行具体知足它。做为结果,这个谓词减小了对来自于部分查询计划的评估的行数。这个更小的行估计一般为后面的查询计划减小了行数和评估成本,而有时选择不一样计划的结果是由于不一样候选计划之间的相关评估条件改变了。

为何这个什么都不作的谓词有时候却会提升查询性能?增长谓词“ no-op ” coalesce() 引入了一个错误掩盖了一些东西,要否则就是阻止了性能优化。

一些性能加强工具作了什么是一个强力测试:工具一再引入谓词到一个查询的不一样位置,操做不一样的列,经过引入一个错误来尝试找到一种状况,这个错误出如今哪里影响了一个更好的查询计划。这也是一个真正的查询语句开发人员在一个查询中手动。编写“ no-op ”谓词。一般,开发人员会获得一些对数据的了解来指导这个谓词的放置。

使用这个方法来提升查询性能是一个短时间的解决方案,它并无定位根本缘由并且会有如下影响:

  • 性能提高的潜力被掩盖了。
  • 不能保证这个 workaround 会提供永久的性能提升,就像 DB2 查询编译器可能最终更好的处理这个谓词或者其余随机因素可能影响了它。
  • 或许会有其余语句受到相同的缘由影响并且对系统性能的影响一般会由你的系统承受。

避免不相等的链接谓词

链接谓词使用比较操做,除了相等其余都应该避免。由于不相等链接方法就会限制为嵌套循环。并且,优化器或许不能为链接谓词计算一个精确的可选评估。然而不等链接谓词不能永远规避。当它们是必须的时候,确保一个谓词索引存在于任何一个表中,由于链接谓词将应用嵌套内部链接。

不等链接谓词的一个简单例子是,为了精确反映维度数据在不一样的时间点的状态,一个星型模式中的维度数据必须版本化。这经常做为一个‘慢慢改变的维度’来被参考。一类慢慢改变的维度包括每一个维度行的有效的开始和结束日期。为了链接维度的主键,一个在事实表和维度表之间的链接须要检查和事实表相关的数据,包括维度的开始和结束日期。这经常做为一个‘第 6 类慢慢改变的维度’被参考。范围链接回到事实表经过一些实际事务日期以进一步限定维度版本,成本会很高。例如:

SELECT ... FROM 
 PRODUCT P, SALES F 
 WHERE 
 P.PROD_KEY = F.PROD_KEY AND F.SALE_DATE BETWEEN P.START_DATE AND P.END_DATE

在这个状况下,须要确保有一个索引在(F.PROD_KEY, F.SALE_DATE)列上

能够考虑建立一个统计视图来帮助优化器计算一个更好的可选评估。例如

CREATE STATISTICAL VIEW V_PROD_FACT AS 
 SELECT P.* 
 FROM PRODUCT P, SALES F 
 WHERE 
 P.PROD_KEY=F.PROD_KEY and 
 F.SALE_DATE BETWEEN P.START_DATE AND P.END_DATE 

 ALTER VIEW V_PROD_FACT ENABLE QUERY OPTIMIZATION 
 RUNSTATS ON TABLE DB2USER.V_PROD_FACT WITH DISTRIBUTION

指定星型模式链接,好比索引 ANDing 星型链接,而且若是在查询块中有任何不等链接谓词,集中链接不被考虑。(参见“若是你使用星型模式链接,确保你的查询和必须匹配在 12 页中的标准”)

避免出现多个 DISTINCT 关键字

避免使用在同一个 subselect 中运行多个 DISTINCT 集合的查询,它的运行成本很是高。考虑下面的例子:

SELECT SUM(DISTINCT REBATE), AVG(DISTINCT DISCOUNT) FROM DAILY_SALES GROUP BY PROD_KEY;

为了判断 DISTINCT REBATE 值和 DISTINCT COUNT 值,来自 PROD_KEY 表的输入流须要进行两次排序。这个查询语句的查询计划就像这样 :

优化器重写了最初的查询语句,分红两个单独的集合,每一个指定 DISTINCT 关键字,而后把多个集合用 UNION 关键字链接起来。内部重写的语句是:

SELECT Q8.MAXC0, (Q8.MAXC1 / Q8.MAXC2) 
 FROM 
   (SELECT MAX(Q7.C0) AS MAXC0, MAX(Q7.C1) AS MAXC1, MAX(Q7.C2) AS MAXC2 
   FROM 
      (SELECT SUM(DISTINCT Q2.REBATE) as C0 , 
      cast(NULL as integer) AS C1, 0 AS C2, Q2.PROD_KEY 
      FROM 
         (SELECT Q1.PROD_KEY, Q1.REBATE 
         FROM DB2USER.DAILY_SALES AS Q1) AS Q2 
      GROUP BY Q2.PROD_KEY 
      UNION ALL 
      SELECT cast (NULL as integer) AS C0, SUM(DISTINCT Q5.DISCOUNT) AS C1, 
      COUNT(DISTINCT Q5.DISCOUNT) AS C2, Q5.PROD_KEY 
      FROM 
         (SELECT Q4.PROD_KEY, Q4.DISCOUNT 
         FROM DB2USER.DAILY_SALES AS Q4) AS Q5 
      GROUP BY Q5.PROD_KEY) AS Q7 
   GROUP BY Q7.PROD_KEY) AS Q8

若是你不能避免多个 DISTINCT 集合的话,就考虑使用带 ENHANCED_MUTIPLE_DISTINCT 选项的 DB2_EXTENDED_OPTIMIZATION 注册表变量。 这个选项将使到多个 DISTICT 集合的输入流被读取一次而后被 UNION 的每个分支重复使用。这个选项能够在数据库分区的处理器比率较低的时(例如,比率小于或等于 1)提升这类查询的性能。这个设置应该对没有对称的多处理器的 DPF(Database Partitioning Feature)环境(SMPs)颇有用。这个优化扩展不能在全部环境中提升查询性能。应该进行测试来判断单个查询性能的提升。

避免多余的谓词

某些查询的语义须要外链接(无论左、右或全链接)。然而,若是查询语义不须要一个外链接并被用于处理不一致数据,那么最好是处理不一致数据的根本缘由。例如,在一个数据集市中有一个星型模式,事实表可能包含事务数据,不过由于数据不一致的问题,形成与父维度行的一些维度不匹配。这是可能发生的,由于抽取、转换和装载(ETL)过程出于某些缘由不与商业键不兼容。在这种状况下,事实表的行与维度左链接能够确保它们即便在没有父表的状况下获得返回。例如:

SELECT ... FROM DAILY_SALES F 
 LEFT OUTER JOIN CUSTOMER C ON F.CUST_KEY = C.CUST_KEY 
 LEFT OUTER JOIN STORE S ON F.STORE_KEY = S.STORE_KEY 
 WHERE 
 C.CUST_NAME = 'SMITH'

左外链接会阻止一些优化,也包括使用指定的星型模式链接访问方法。然而,在某些状况下左外链接能够自动被查询优化器重写成一个内部链接。在这个例子中,在 CUSTOMER 和 DAILY_SALES 之间的左外链接能够被转换成一个内部链接,由于 C.CUST_NAME= ’ SMITH ’谓词将排除这一列中全部 NULL 值的行,使得一个左外链接语义变得没有必要。因此因为外链接的出现致使那些优化损失可能并不会对全部查询产生负面影响。然而,注意到这些限制并避免外链接很是重要,除非它们是绝对必须的。

把 FETCH FIRST N ROWS ONLY 子句和 OPTIMIZE FOR N ROWS 子句放在一块儿使用

OPTIMIZE FOR N ROWS 子句代表对于优化器应用程序打算只获取 N 行,不过查询将返回完整的结果集。 FETCH FIRST N ROWS ONLY 子句显示查询只需返回 N 行。

DB2 数据服务器不会在为外部子查询指定了 FETCH FIRST N ROWS ONLY 而自动假设 OPTIMIZE FOR N ROWS 。尝试与 FETCH FIRST N ROWS ONLY 一块儿指定 OPTIMIZE FOR N ROWS 来鼓励查询计划直接从引用的表返回行,而不执行一个缓冲操做,好比插入一个临时表、排序或插入一个哈希链接的哈希表。

应用程序指定 OPTIMIZE FOR N ROWS 来鼓励查询计划避免缓冲操做,也不获取整个结果集,它们可能致使性能低下。这是由于快速返回前 N 行的查询计划可能不是对于获取整个结果集的查询计划。

若是你正在使用星型模式的链接,请确保你的查询知足须要的标准

优化器为星型模式考虑两个特殊的链接方法,叫作一个星型链接或集中链接,它们能够明显的提升性能。若是查询必须知足如下标准。

  • 对每一个查询块
    • 最少 3 个不一样的表被链接
    • 全部链接谓词必须相等
    • 没有子查询存在
    • 在表与表之间或者查询块之间不存在相关性或依赖性
    • 另外,对于索引 ANDing,必须没有不肯定的函数,由于为方便 semi-joins 事实表的谓词必须经过索引来应用
  • 事实表
    • 是查询块中最大的表
    • 少于 10000 行
    • 被视为只有一个表
    • 必须链接到至少两个维度表或叫作 snowflakes 的组。
  • 维度表
    • 不是事实表
    • 能够单据链接到实施表或在 snowflakes 中
  • 一个维度表或者一个 snowflake 。
    • 必须过滤实施表(基于优化器的评估结果来过滤)
    • 必须有一个链接谓词到实施表,它使用了实施表索引中主要的列。这个规范必须知足,无论是考虑星型链接或集中链接,即便集中链接将至须要使用一个单独的事实表索引。

一个查询块表现一个左外部连接或右外部链接,能够只涉及两个表,因此不符合一个星型模式的链接

不须要为优化器能发现一个星型模式链接而显示的声明参考完整性。

避免多余的谓词

避免多余的谓词,尤为是当他们发生在不一样的表的时候。在某些状况下,优化器并不能判断多余的谓词。这可能致使基数被低估。

例如,在 SAP BI 应用程序中雪花模式和实施表以及维度表被做为一个查询优化数据结构被用到。在一些状况下会有多余的时间特征列(对于月的“ SID_0CALMONTH ”或对于年的 "SID_0FISCPER")定义在事实表和维度表中。

SAP BI OLAP 处理器在维度和事实表的时间特征列上会产生多余的谓词。

这些多余的谓词可能产生很长的运行时间。

下面提供了一个例子,在一个 SAP BI 查询中有两个多余的谓词被定义在 WHERE 条件里。相同的位谓词定义在时间维度(DT)和事实(F)表。

AND  (     "DT"."SID_0CALMONTH" = 199605  
           AND "F". "SID_0CALMONTH" = 199605 
            OR "DT"."SID_0CALMONTH" = 199705 
           AND "F". "SID_0CALMONTH" = 199705 ) 
 AND NOT (     "DT"."SID_0CALMONTH" = 199803 
           AND "F". "SID_0CALMONTH" = 199803 )

DB2 优化器没有注意到相同的谓词,并对它们分别处理。这致使低估了谓词、生成不是最优的访问计划以及更长的查询运行时间。

处于这个缘由多余的谓词从 DB2 数据库具体平台软件层面去掉了。

以上谓词转换成下面这一个。只有事实表“ SID_0CALMONTH ”列上的谓词被保留:

AND  (     "F". "SID_0CALMONTH" = 199605 
            OR "F". "SID_0CALMONTH" = 199705 )  
 AND NOT (      "F". "SID_0CALMONTH" = 199803 )

应用 SAP 957070 和 1144883 备忘录来去掉多余的谓词。

回页首

设计并配置你的数据库

有不少数据库设计和配置选项能够影响查询性能。对数据库设计的更多建议参考“ Planning your Physical Database Design ”最佳实践文章。

使用约束来提升查询优化

考虑定义的惟一性,检查并参考一致性约束。这些约束提供了语义信息,容许 DB2 优化器重写查询来评估链接,经过链接来下降聚合和 FETCH FIRST N ROWS,去掉没必要要的 DISTINCT 选项被和一些其它的优化。当应用程序能够保证它本身的关系时,信息约束也能够被用来检查并参考一致性约束。相同的优化也是能够的。当更新(插入或删除)行的时候,来自数据库管理器的强制约束可能致使很高的系统开销,尤为在更新不少有一致性约束的行的时候。若是一个应用程序在更新一行以前已经验证的信息,这样使用信息约束比起正常的约束更有效

例如,考虑 2 个表 DAILY_SALES 和 CUSTOMER 。在 CUSTOMER 表中的每一行都有一个惟一的客户键值(CUST_KEY)。 DAILY_SALES 包含一个 CUST_KEY 列而且每一行都引用一个 CUSTOMER 表中的客户键。能够建立一个参考一致性约束来防止在 CUSTOMER 和 DAILY_SALES 之间发生 1:N 的关系。若是应用程序要强制约束这个关系,能够建立一个信息化的约束。那么下面的查询避免了在 CUSTOMER 和 DAILY_SALES 之间进行链接,由于没有从 CUSTOMER 获取任何列,并且来自于 DAILY_SALES 的每一行均可以在 CUSTOMER 里面找到与之匹配的行,因此查询优化器将自动删除链接

SELECT AMT_SOLD, SALE PRICE, PROD_DESC 
 FROM DAILY_SALES, PRODUCT, CUSTOMER 
 WHERE 
 DAILY_SALES.PROD_KEY = PRODUCT.PRODKEY AND 
 DAILY_SALES.CUST_KEY = CUSTOMER.CUST_KEY

应用程序必须执行信息约束,不然查询可能返回不正确的结果。在上面的例子中,若是行存在于 DAILY_SALES 中,在 CUSTOMER 表中却找不到相应的客户键,那么上面的查询返回的行可能不正确。

在复杂查询中使用 REOPT 绑定选项和输入变量

在一个在线事务处理(OLTP)环境的中输入变量有较好的语句准备时间是关键,在这样的环境中语句每每比较简单并且查询计划选择也很简单。使用不一样的输入变量屡次运行相同的语句能够复用在动态语句高速缓存中编译了的访问片断,避免了因为随时更改输入值而形成昂贵的 SQL 语句编译开销。

然而,输入变量对复杂的查询负载也会形成问题,它们的查询计划选择很是复杂,所以优化器须要更多的信息来作出好的决定。并且,语句编译时间一般是总运行时间中的一个很小组成部分。由于 BI 查询一般不会重复,因此并无从动态语句高速缓存上获得好处。

若是在一个复杂查询工做负载中须要使用输入变量,请考虑使用 REOPT(ALWAYS) BIND 选项。当输入变量值是已知的,REOPT BIND 选项从 PREPARE 到 OPEN 或执行过程当中推迟了语句编译。变量值被传递到 SQL 编译器中,这样优化器可使用这些便利来计算一个更精确的选择评估。 REOPT(ALWAYS) 表示全部执行语句都应该被预编译。 REOPT(ALWAYS) 也能够被用于涉及特殊寄存器的复杂查询,好比 "WHERE TRANS_DATE = CURRENT DATE - 30 DAYS" 。若是输入变量对 OLTP 工做负载形成较差的访问计划选择,而且 REOPT(ALWAYS) 选项由于语句编译形成过多的开销,那么考虑对挑选过的查询使用 REOPT(ONCE) 。 REOPT(ONCE) 推迟语句的编译直到首个数据变量被绑定。使用这个首个输入变量值编译并优化 SQL 语句。后续使用不一样的值来运行的语句将重用基于第一个输入编译的查询片断。这是一个好方法 , 若是首个输入变量表明了后续的输入值,而且在输入值未知的状况下比起优化器使用不一样的值进行评估,它提供个了一个更好的查询访问计划 .

有不少方法来指定 REOPT:

  • 对 C/C++ 应用程序中的嵌入式 SQL,使用 REOPT BIND 选项。这个 BIND 选项影响静态和动态 SQL 的再优化行为。
  • 对 CLP 包,用 REOPT 绑定参数从新绑定 CLP 包。例如,使用 CS 隔离级别和 REOPT ALWAYS 来从新绑定 CLP 包,详细命令:

    rebind nullid.SQLC2G13 reopt always;

  • 对使用传统 JDBC 驱动的 CLI 应用程序或 JDBC 应用程序,在 db2cli.ini 中设置 REOPT 关键字。选项的值是:
    • 2 - NONE
    • 3 - ONCE
    • 4 - ALWAYS
  • 对于使用 JCC 通用驱动的 JDBC 应用程序,使用下面的方法之一:
    • 使用 SQLATTR_REOPT 链接或语句属性。
    • 使用 SQL_ATTR_CURRENT_PACKAGE_SET 链接或语句属性来制定 NULLID、NULLIDR1 或 NULLIDRA 包集合。 NULLIDR1 和 NULLIDRA 是保留的包集合名称。一旦使用就分别隐含了 REOPT ONCE 和 REOPT ALWAYS 。这些包集合须要于那个下面命令显示的建立:
      db2 bind db2clipk.bnd collection NULLIDR1;
      db2 bind db2clipk.bnd collection NULLIDRA;

  • 对 SQL PL 存储过程使用下面的方法之一:
    • 使用 SET_ROUTINE_OPTS 存储过程来为在当前会话中建立 SQL PL 存储过程设置绑定选项,例如调用 sysproc.set_routine_opts( ‘ reopt always ’ )
    • 使用 DB2_SQLROUTINE_PREPOPTS 注册表变量在实例级别设置 SQL PL 存储过程选项。值设置为使用 SET_ROUTINE_OPTS 存储过程将覆盖 DB2_SQLROUTINE_PREPOPTS 指定的值

你可也能使用优化配置来为静态语句和动态语句设置 REOPT,以下面例子显示的:

<STMTPROFILE ID="REOPT example "> 
    <STMTKEY> 
      <![CDATA[select acct_no from customer where name = ? ]]> 
    </STMTKEY> 
    <OPTGUIDELINES> 
      <REOPT VALUE='ALWAYS'/> 
  </OPTGUIDELINES> 
 </STMTPROFILE>

为你的工做负载选择最佳的优化级别

设置优化级别能够得到显式指定优化技术的好处,尤为出于下面的缘由:

  • 为了管理很是小的数据库或者很是简单的查询语句
  • 为了在你的数据库服务器编译时进行内存限制
  • 为了减小查询编译时间,好比 PREPARE

大多数语句能够经过使用第 5 级优化获得充分的优化和合理的资源,这也是默认的查询优化级别。在一个给定的优化级别,查询编译时间和资源消耗是主要受查询复杂度的影响,尤为是链接以及子查询的数目。不过,编译时间和资源的使用一样受到执行优化的影响。

查询优化级别 1,2,3,5 和 7 适用于通常用途。只有你须要进一步减小查询优化时间并且在你知道 SQL 语句很是简单的状况下才考虑级别 0 。

Tip:要分析一个运行很长时间的查询,对查询运行 db2batch 来找出花了多少时间在编译上在运行上花费了多少时间。若是编译须要更多的时间,下降优化级别。若是执行须要更多的时间那么就考虑更高的优化级别

当你选择了一个优化级别,考虑下面的通常准则:

  • 从使用默认查询优化级别开始,级别 5
  • 要使用默认级别以外的级别,首先尝试级别 1,2 或 3 。级别 0,1 和 2 使用贪婪链接枚举运算法则。
  • 若是你有不少表以及在同一列上有大量的链接谓词,在关心编译时间的状况下使用优化级别 1 或 2 。
  • 对只有不到一秒的运行时间的查询使用一个低的优化级别(0 或 1)。好比查询每每有下面的特色:
    • 只访问一个或不多的表
    • 只获取一行或者几行
    • 使用彻底惟一的索引

在线事务处理(OLTP)事务是这种类型访问的很好例子

  • 对长时间运行(超过 30 秒)的语句使用高一些的优化级别(3,5 或 7)。

    优化级别 3 及其以上使用动态编程链接枚举算法。这个算法考虑更多的可选计划,而且可能招致比 0,1,和 2 更多的编译时间,尤为在表的数目增长后。

  • 只有在你对一个查询有特别的优化需求时才使用优化级别 9 。

复杂查询须要不一样数量的优化来选择最佳访问计划。对有下面特征的查询,请考虑使用更高的优化级别:

  • 访问一个大表
  • 谓词数目不少
  • 大量的子查询
  • 不少链接
  • 不少集合操做,好比 UNION 和 INTERSECT
  • 不少匹配的行
  • 有 GROUP BY 何 HAVING 操做
  • 嵌套表描述
  • 大量的视图

决策支持查询或月底报告查询对于数据库是一个很常见的复杂查询的很好例子,对于这类查询优化级别至少应该使用默认值。

使用更高的查询优化级别的 SQL 语句是由查询生成器产生的。不少查询生成器建立效率低下的查询。写得很拙劣的查询,包括那些有查询生成器产生的查询,须要额外的优化以选择一个好的访问计划。使用查询优化级别 2 和更高的级别能够提升那些 SQL 查询。

对于 SAP 应用程序,老是使用优化级别 5 。这个优化级别启用了不少为 SAP 优化过的 DB2 功能,好比设置 DB2_REDUCED_OPTIMIZATION 注册表变量。

使用参数标记来减小动态语句的编辑时间

DB2 数据服务器能够经过在动态语句高速缓存中保存访问片断和语句文原本避免重复预编译一个前面运行过的动态 SQL 语句。对这个语句的一个后续 PREPARE 请求将尝试在动态语句高速缓存中查找访问片断来避免编译。然而,只要谓词在字面上有一点不一样,这个语句高速缓存中的片断就不一致。例如,下面两个语句就在动态语句高速缓存中被看做不一样的语句。

SELECT AGE FROM EMPLOYEE WHERE EMP_ID = 26790 
 SELECT AGE FROM EMPLOYEE WHERE EMP_ID = 77543

若是它们运行得太频繁,相关 SQL 语句的编译甚至会形成额外的系统 CPU 负担。在“ Monitoring and Tuning the System ”最佳实践文章中描述了 如何检测这性能问题。若是你的系统遇到这类性能问题,应该考虑把应用程序改为使用参数标记来把谓词的值传递给 DB2 编译器,而不要显式的在 SQL 语句中包含它。不过,对于复杂的查询若是使用参数标记那么获得的访问计划可能不是最优的。更多信息请参见“在复杂查询中使用 REOPT 绑定选项和输入变量”。

设置 DB2_REDUCED_OPTIMIZATION 注册表变量

若是对你的应用程序设置的优化级别不能充分的减小编译时间,那么就尝试设置 DB2_REDUCED_OPTIMIZATION 注册变量。这个注册变量在优化器查找空间上比设置优化级别提供了更多控制。这个注册变量让你能够请求在指定的优化级别中减小优化功能或者严格使用优化功能。若是你减小了使用优化技术的数目,你一样减小了时间和优化过程当中使用的资源。

注意:虽然优化时间和资源使用可能会减小,这也增长了产生的查询计划不是最优的风险。

首先,尝试设置注册表变量为 YES 。若是优化级别是 5(默认值)或更低,优化器将不会使用某些须要花费大量准备时间和资源的优化技术,可是一般也不会产生更好的查询计划。若是优化级别是 5,优化器会减小或取消一些额外的技术,这可能进一步减小优化时间和使用的资源,不过一样进一步增长了获得的查询计划不是最优的风险。对于低于 5 的优化级别,它们的一些技术可能在任何状况下都无效。

若是设置 YES 没能充分缩短编译时间,能够尝试设置这个注册变量为一个数字。效果是和 YES 同样,对于在级别 5 上的动态准备查询优化有后续的附加行为。若是在任何查询块中链接的总数目超过了这个设置,那么优化器就切换到一个贪婪链接枚举算法而不是取消额外的优化技术。这样的效果是查询将在一个相似优化级别 2 的级别上被优化。

对 SAP 应用程序设置 DB2_WORKLOAD 注册变量

对于 SAP 应用程序,老是会为 SAP 设 DB2_WORKLOAD 注册变量。这会触发一批其余的对 SAP 应用程序有特殊好处的 DB2 注册表变量设置。下面是在这些便利中和 DB2 优化器相关的注册变量设置

  • DB2_MINIMIZE_LIST_PREFETCH=YES
  • DB2_INLIST_TO_NLJN=YES
  • DB2_ANTIJOIN=EXTEND
  • DB2_REDUCED_OPTIMIZATION=<specific heuristics for SAP workloads>
  • DB2_VIEW_REOPT_VALUES=YES

DB2_REDUCED_OPTIMIZATION 的设置是专门针对 SAP 工做负载的。不要在其余应用程序下使用除非是 DB2 技术支持推荐的。

  • DB2_MINIMIZE_LIST_PREFETCH=YES 如没有足够可用信息来判断是否这个访问方法对查询有好处,将会阻止优化器考虑列出预取表访问方法。若是谓词包含参数标记,这可能对实例就是这种状况。在 SAP 应用程序中,参数标记在大多数应用程序中都有使用,除了 SAP NetWeaver BIreport 查询。
  • DB2_INLIST_TO_NLJN=YES 使优化器支持包含列表谓词 IN 的查询使用嵌套循环链接。 IN 列表被转换进一个表并像外部表的 NLJN 和经过索引访问的内部表使用。在 SAP 应用程序中常常有 IN 列表的查询,例如当使用 SAP 的 F4 帮助功能来从一个可能的值的列表中选择一个范围或一批不一样的值。

    即便在指定了 REOPT(ONCE) 的状况下,DB2_MINIMIZE_LIST_PREFETCH=YES 和 DB2_INLIST_TO_NLJOIN=YES 将依然保持活动。

  • DB2_ANTIJOIN=EXTEND 让优化器去寻找把 NOT IN 和 NOT EXISTS 子查询转换成 anti-joins 的机会。
  • DB2_VIEW_REOPT_VALUES=YES 让全部 SAP 用户去存储一个当语句被解释的时候在 EXPLAIN_PREDICATE 表中从新优化过的 SQL 语句的缓存的值。全部 SAP 用户使用相同的具备所需权限的数据库链接用户。

收集正确的编目信息,包括高级统计功能

精确的数据库统计信息是查询优化的关键。在全部对查询性能来讲很是关键的表上有规律的运行 RUNSTATS 。若是一个应用程序直接查询这些表而且有大量的动态编目更新好比 DDL 语句,你可能也但愿搜集系统编目表的信息。能够启用自动搜集统计信息功能来容许 DB2 数据服务器自动运行 RUNSTATS 。能够启用实时收集统计信息,经过马上收集这些信息来让 DB2 数据服务器在优化查询以前能提供更及时的统计信息。

若是手动运行 RUNSTATS 来收集统计信息,你应该至少使用下面的选项。

RUNSTATS ON TABLE DB2USER.DAILY_SALES WITH DISTRIBUTION AND SAMPLED DETAILED INDEXES ALL

分发统计信息可让优化器知道是否有数据倾斜。当使用特定索引访问表时,详细的索引统计信息提供更多的 I/O 需求细节来预取数据页。然而对大表收集详细的索引统计信息会消耗不少的 CPU 和内存。 SAMPLED 选项提供了详细索引统计信息和相同的精确性,却只须要一小部分 CPU 和内存。当并无对一个表提供一个统计配置文件时,这些默认值一样会被自动收集统计信息使用。

为了提升查询性能,考虑收集更多更高级的统计信息,好比列组的统计信息,LIKE 统计信息或建立统计信息视图。

列组统计信息

若是你的查询不止一个链接谓词来链接两个表,在选择一个执行计划来运行查询以前 DB2 优化器将计算如何选择每一个谓词。

例如,考虑以供厂商,他用有不少颜色的原料生产产品,弹性和品质。产品最后页是和原料同样的颜色。这个厂商执行了如下查询:

SELECT PRODUCT.NAME, RAWMATERIAL.QUALITY 
 FROM PRODUCT, RAWMATERIAL 
        WHERE PRODUCT.COLOR       =  RAWMATERIAL.COLOR 
          AND PRODUCT.ELASTICITY  =  RAWMATERIAL.ELASTICITY

这个查询返回了全部产品的名字和原材料品质。在这里有两个链接谓词:

PRODUCT.COLOR       =  RAWMATERIAL.COLOR 
   PRODUCT.ELASTICITY  =  RAWMATERIAL.ELASTICITY

优化器会假定这两个谓词是独立的,也就是说全部弹性对颜色的变化没有关系。而后经过创建每一个表关于弹性等级数和不一样的颜色数目的编目信息评估谓词的总的可选组合,并基于这个评估。例如,比起合并链接它可能更倾向于选择一个嵌套循环链接,反之亦然。

然而,这两个谓词可能并不独立。例如比较高的弹性材料可能只有几种颜色,并且弹性差的材料也可能不一样于弹性好的材料只有剩下的其余颜色。而后组合这些谓词的选择消除一些行,因此查询将返回更多的行。没有这些信息,优化器也许不会选择最佳的计划。

为了在 PRODUCT.COLOR 和 PRODUCT.ELASTICITY 上收集列组统计信息 , 运行下面 RUNSTATS 命令:

RUNSTATS ON TABLE product ON COLUMNS ((color, elasticity))

优化器使用这些统计信息来检测相关性,并动态调整相关的谓词选项组合,所以获得对链接的尺度和开销更精确的评估。

当一个查询须要数据以一个具体的方式(使用 GROUP BY 或 DISTINCT 关键字)编组时列组统计信息也会很是有用,由于优化器须要计算明确分组的数目。

考虑下面查询:

SELECT DEPTNO, YEARS, AVG(SALARY) 
  FROM EMPLOYEE 
 GROUP BY DEPTNO, MGR, YEAR_HIRED

没有任何索引或列组统计信息,优化器评估分组的数目(也包括在这种状况下返回的行数目)是 DEPTNO、MGR 和 YEAR_HIRED 的不一样值的结果。这个评估假设分组键列是独立的。然而,若是每一个管理员管理一个肯定的部门,这个假设就多是错误的。一样,不大可能每一个部门每一年都雇用新员工。所以,不一样 DEPTNO、MGR 和 YEAR_HIRED 值得结果多是对具体组的数目太高评估。

在 DEPTNO、MGR 和 YEAR_HIRED 上收集的列组统计信息将为上面的查询提供给优化器和有肯定数目的分组:

RUNSTATS ON TABLE EMPLOYEE ON COLUMNS ((DEPTNO, MGR, YEAR_HIRED))

为了 JOIN 谓词关系,优化器也管理简单等价谓词,好比

DEPTNO = ” Sales ” AND  MGR = “ John ”

在上面的 EMPLOYEE 表,在 DEPTNO 谓词上极可能与在 YEAR 上的谓词毫无关系。然而在 DEPTNO 和 MGR 上的谓词却确定相关,由于每一个单独的部门可能常常在一段时间受到同一个经理的管理。优化器使用列的统计信息来判断不一样之的组合数目并对这两列的关系调整选择或计数评估。

子元素统计

若是你在模式结尾以外的任何位置对指定的 LIKE 谓词使用 % 通配符,你都应该搜集关于子元素结构的基本信息。

以及向通配符 LIKE 谓词(例如,SELECT .... FROM DOCUMENTS WHERE KEYWORDS LIKE '%simulation%'),这列以及查询必须知足某些标准来从子元素统计信息中获利。

表列应该包括由空格分开的子域或者子元素。例如,一个四行的 DOCUMENTS 表出于文本检索的目的有一个 KEWORDS 列和一系列相关的关键字。 KEYWORDS 的值是:

'database simulation analytical business intelligence' 
 'simulation model fruit fly reproduction temperature' 
 'forestry spruce soil erosion rainfall' 
 'forest temperature soil precipitation fire'

在这个例子中,每列的值有 5 个子元素组成,每一个都是一个词(关键词),经过空格和其余关键词分隔开。

查询应该在 WHERE 子句中参考这些列。

优化器会评估每一个谓词匹配多少行。对于这些通配符 LIKE 谓词,优化器假设 COLUMN 匹配了一系列彼此链接的元素,而且它基于字符串的长度来估算每一个元素的长度,除了 % 开头或结尾的字符。若是你收集子元素的统计信息,优化器将有关于每一个子元素和分隔符的长度信息。它可使用这些额外的信息来更精确的评估可能有多少行匹配这个谓词。

为了链接子元素统计信息,运行有 LIKE STATISTICS 子句的 RUNSTATS 。

统计视图

DB2 基于成本的优化器把一个基于访问计划处理器处理的行数 – 或基数的评估做为这个操做的精确成本。这个基数评估是优化器成本惟一最重要的输入,并且它的精确度很大程度上取决于 RUNSTATS 实用工具从数据库收集的统计信息。对于计算一个精确的基数评估来讲上面描述的统计信息是最重要的,然而有一些环境却须要很是成熟的统计信息。尤为是想要体现越复杂的关系就更须要成熟的统计信息,好比涉及比较的描述(例如,price > MSRP + Dealer_markup),关系跨了多个表(例如,product.name = 'Alloy wheels' and product.key = sales.product_key),或者其余谓词除了涉及独立属性以及简单比较操做的谓词。统计视图能够防止这些复杂关系类型,由于统计信息是在这个视图返回值的基础上收集的,而不是从这个视图相关的基础表上。

当一个查询被编译时,优化器把这个查询和可用的统计视图进行匹配。当优化器计算基数估算中间结果集时,它使用来自视图的统计信息来计算一个更好的评估。

查询没必要由于优化器使用视图就直接参考统计视图。优化器可使用和物化查询表(MQTs)相同的匹配机制来匹配到统计视图的查询。出于这个考虑,除了他们不被永久储存,统计视图和 MQTs 很是类似,所以它们也不消耗磁盘空间也不须要维护。

一个统计视图在第一次建立一个视图并使用 ALTER VIEW 语句容许优化。而后在这个统计视图上运行 RUNSTATS,用这个视图的统计信息填入系统编目表中。例如为了建立一个统计视图来表如今时间在一个星型模式中维度表和实施表之间的链接,执行下面语句:

CREATE VIEW SV_TIME_FACT AS ( 
           SELECT T.* FROM TIME T, SALES S 
           WHERE T.TIME_KEY = S.TIME_KEY) 

 ALTER VIEW SV_TIME_FACT ENABLE QUERY OPTIMIZATION 
 RUNSTATS ON TABLE DB2DBA.SV_TIME_FACT WITH DISTRIBUTION

统计视图能够被用于对查询提升基数评估,以及访问计划和查询性能,例如:

SELECT SUM(S.PRICE)  
  FROM SALES S, TIME T,  PRODUCT P 
  WHERE 
  T.TIME_KEY = S.TIME_KEY AND T.YEAR_MON = 200712 AND 
  P.PROD_KEY = S.PROD_KEY AND P.PROD_DESC = ‘ Power drill ’

没有统计视图,优化器假设全部事实表 TIME_KEY 的值对应一个特定的时间维度 YEAR_MON 值在事实表中是统一的。然而可能销售在 12 月特别强劲,产生比其余月份强劲多不少的交易。

在不少状况下,统计视图能够提升查询性能,而且有一些简单的最佳实践能够帮助判断须要建立哪些统计视图。请参考“更多阅读”章节。

自动收集统计信息当前不能用于统计视图。不管何时统计视图的基础表数据有了显著的改动都要收集统计视图的统计信息。

最小化 RUNSTAS 的影响

进一步改善 RUNSTATS 的时机:

  • 经过 COLUMNS 子句来限制要收集统计信息的列。在查询工做负载中常常会有一些列永远都不会被谓词涉及到,所以它们不须要被统计。
  • 若是倾向于一致的数据就限制搜集分布统计信息的列数。收集分布统计信息须要比收集基础列统计花费更多的 CPU 和内存。不过,要判断一列的值是否相同须要现有的统计信息或者对数据进行查询。由于表会发生改变,这个方法一样基于数据将保持一致的假设。
  • 经过制定 TABLESAMPLE SYSTEM 或 BERNOULLI 子句使用页面或行级别的取样来显示处理的行数和页面的数目。从 10% 级别的样本开始例如 TABLESAMPLE SYSTEM(10) 。检查统计信息的精确性以及系统性能是否由于更改访问计划而有所降低。若是是的话,就尝试用 10% 行级别的样原本替换,好比 TABLESAMPLE BERNOULLI(10) 。若是统计信息精度不够,则增长取样数量。当使用 RUNSTATS 页面或行级别的取样,对进行链接的表使用相一样本率。这和确保链接列统计信息有相同级别的精度。

对一个配置了数据库分区功能(DPF)的数据服务器,RUNSTATS 从单个数据库分区搜集统计信息。若是 RUNSTATS 运行在表所在的这个数据库分区上,统计信息将在这里收集。若是不是,统计信息将从第这个表所在分区组的一个数据库分区上收集。为了保持一致的统计信息,就要确保进行链接的表的统计信息从相同的数据库分区搜集。

避免手动更新编目统计信息

DB2 数据服务器支持经过对 SYSSTAT 模式下的视图发起 UPDATE 语句手动来更新编目统计信息。这个功能对在测试系统中模拟一个生产数据库来检查查询计划,或许很是有用。为了在其余系统上重放,db2look 工具对抓取 DDL 和 UPDATE SYSSTAT 语句方面颇有帮助。

然而,要避免手动更新统计信息 - 意味着为了强制执行一个特定的查询计划经过提供不正确的统计信息影响查询优化器。这个实践可能形成某些查询的性能提高,也可能致使其余的性能降低。在最终使用这个办法以前,请考虑其它以前考虑过的调优方法。若是不得不使用这个方法,在这种状况下必定要记录原始的统计信息,若是更新统计信息形成了性能降低就须要恢复它们。

对 SAP 应用程序,使用自动统计信息收集

在 SAP 安装过程当中,自动和实施统计信息是默认打开的。这就是说你不须要手动发起 RUNSTATS 。

不少 SAP 使用状况是在第一步以及经过一个复杂的 SAP 文本查询来访问修改表内容。不要改变下面提到的默认设置 :

Automatic maintenance                    (AUTO_MAINT) = ON 

 Automatic table maintenance         (AUTO_TBL_MAINT) = ON 

  Automatic runstats                  (AUTO_RUNSTATS) = ON 

   Automatic statement statistics   (AUTO_STMT_STATS) = ON 

    Automatic statistics profiling (AUTO_STATS_PROF) = OFF 

     Automatic profile updates       (AUTO_PROF_UPD) = OFF

使用有不均匀数据的 SAP BI 表的统计视图

在 SAP BI snowflake 模式的表中不均匀的分布数据可能致使并不优化的查询访问计划并增长查询时间。大多数这样的问题是经过设置 SAP 工做负载变量 =SAP 来解决的。可是在一些例外的状况下,当不少表互相链接时,统计视图能够被建立来为 DB2 优化器提供更多关于值分布的信息。

下面的例子中,事实表和客户、请求、时间以及产品维度表进行链接。

大多数交易是跟 Customer #10200 完成的。所以,事实表的绝大多数行在 Dim C 列的值是 2 。这形成了在事实表的 Dim C 列上的不均匀的数据分布。

DB2 优化器可能会在对在客户维度有约束的查询时候估算出错误的基数

能够在维度和事实表上定义统计视图生成额外的统计信息,DB2 优化器利用这些信息来加强基数评估并减小查询运行时间。

在上面的例子中,下面在客户和事实表维度上的统计视图可能解决错误基数统计问题并减小查询响应时间:

CREATE VIEW stat_view as 
	 ( SELECT cust.c, cust.customer#, cust.region, f.dimC 
         FROM customer_ 维度 cust, 
		    fact_table fact 
         WHERE cust.c =  fact.dimC )

若是这个统计视图的一个基本表发生了改动,就须要在统计视图上更新数据库统计信息。统计视图不支持 DB2 自动统计信息搜集。

使用 SAP BI 汇集

SAP BI 实施了它们本身的物化查询表,叫作 SAP BI 汇集。使用 SAP 汇集在 SAP BI 应用程序中替代通常的 DB2 物化查询表。

若是其余调优选项不能产生能够接受的效果那么使用优化配置文件

若是你已经遵循了本文推荐的最佳实践,而你相信仍然没有达到最优的性能的话,你就能够向 DB2 优化器提供一个明确的优化指南。

优化指南包含在一个叫作优化配置文件的 XML 文档中。配置文件定义 SQL 语句和他们相关的优化指南。

若是你普遍的使用了优化配置文件,它们须要你付出不少的努力来维护。更重要的是,你只能使用优化配置文件来对现有 SQL 语句提升性能。下面的最佳实践对全部的查询持续稳定的提升查询性能,包括将来的某些查询。

回页首

使用解释工具来调优 SQL 语句

解释工具是用来显示被查询优化器用来运行一个 SQL 语句的查询访问计划。它包含了用于运行 SQL 语句关于相关操做很是普遍的信息,好比计划操做去、它们的 arguments、执行顺序和成本。由于查询访问计划是查询性能中最重要的因素之一,为了能诊断查询性能问题,可以理解解释工具的输出很是重要。

解释信息一般用于:

  • 理解为何应用程序性能发生了变化
  • 评估性能调优的效果

分析性能变化

为了帮助你理解查询性能变化的缘由,须要调优先后的解释信息,你能够经过执行下面步骤获得它们:

  1. 在你作任何更改以前,抓取查询的解释信息并保存解释表。另外,也能够保存 db2exfmt 解释工具的输出。然而,为了更成熟的分析,把解释信息保存在解释表中能够更方便用 SQL 查询,又提供了把数据保存在关系型 DBMS 中在维护上明显的优点。此外 db2exfmt 工具能够在任什么时候间运行。
  2. 若是你不想、或不能访问 Visual Explain 来查看这些信息,就保存或打印当前编目统计信息。你也可使用 db2look 生产力工具来帮助执行这个任务。另外,若是是你用 DB2 9.5,在语句被解释的同时搜集解释快照。 Db2exfmt 工具将自动格式化包含在快照中的信息。这在使用自动或是统计信息收集的时候尤为重要,由于查询优化器使用的统计信息可能尚未存入系统编目表中,或者他们可能在语句从系统编目表中获取信息到被解释的过程当中被更改了。
  3. 保存或打印数据定义语言(DDL)语句,包括这那些 CREATE TABLE、CREATE VIEW、CREATE INDEX、CREATE TABLESPACE 。 Db2look 一样能够执行这个任务。

经过这个方法收集的信息,为未来的分析提供了一个参考点。对动态 SQL 语句来讲,当你第一次运行你的应用程序时,你能够搜集这个信息。对于静态语句,也能够在绑定的时候搜集这个信息。在一个主要系统更改以前搜集这个信息很是重要,好比安装一个新的服务级别或 DB2 版本或者一个很大的配置改动,好比增长或删除数据库分区和分布数据。这是由于这类系统更改可能形成访问计划的不利更改。虽然访问计划退步应该不多发生,可是有这些可用信息将容许更快的你解决性能退步的问题。要分析一个性能变化,把以前的信息和如今你开始分析的时候收集到的关于查询和环境的信息进行比较。

一个简单的例子,你的分析可能显示索引再也不做为访问计划的一部分被用到。使用 Visual Explain 或 db2exfmt 显示的编目统计信息,你可能注意到 index 级别数远远高于查询第一次绑定到数据库的时候的值。而后你能够选择执行下面的某个操做:

  • 重组索引
  • 为你的表和索引搜集新的统计信息
  • 在从新绑定的时候搜集解释信息。

在你执行其中某个操做以后,再检查一下查询计划。若是索引再一次被使用了,这个查询的性能可能再也不是个问题。重复这些步骤直到问题被解决。

评估性能调整效果

你能够进行一系列的操做来帮助提升查询性能,好比校对配置参数、添加容器、和搜集刷新编目统计信息。

在你这些方面进行了更改,若是在被访问计划选择到的方面有更改的话,你可使用解释工具来判断影响。例如,若是你基于索引指南添加一个索引或物化查询表(MQT),解释数据能够帮助你判断是否索引或物化查询表最终如你所指望的被用到了。

虽然解释输出提供了让你判断选中的访问计划的信息和成本,对一个查询来讲精确测量性能提升的惟一方法是使用基准的是技术。