在PLAN_TABLE实例中指定访问路径

您尝试通过创建PLAN_TABLE访问路径,为特定单一授权ID发出的SQL语句强制使用特定的访问路径。

准备工作

开始特定程序编程接口信息。满足以下前提条件。
  • 准备管理访问路径。
  • PLAN_TABLE表的一个实例将在发出SQL语句的授权ID下创建。
  • 在PLAN_TABLE的下列列上创建索引:
    • QUERYNO
    • APPLNAME
    • PROGNAME
    • 版本
    • COLLID
    • OPTHINT

    SDSNSAMP库的成员DSNTESC中包含创建索引的示例语句。

关于本任务

当您指定PLAN_TABLE访问路径时,它仅适用于特定的SQL语句,且仅适用于由拥有PLAN_TABLE实例的授权ID发出的该语句的实例,其中PLAN_TABLE实例包含指定的访问路径。Db2 对于其他授权ID发出的同一语句的实例,不使用指定的访问路径。

您可以使用其他方法来影响对语句的多个实例的访问路径选择,而与发出语句的授权ID无关。 有关在语句级别指定访问路径的更多信息,请参阅在语句级别指定访问路径

虽然可以使用PLAN_TABLE访问路径来指定 Db2 尝试强制使用现有访问路径,但防止静态SQL语句在重新绑定时更改访问路径的首选方法是指定APREUSE绑定选项。 同样,在准备动态 SQL 语句时,防止访问路径更改的首选方法是指定计划管理策略。 有关访问路径重用的更多信息,请参阅绑定和重新绑定时访问路径的重用和比较

过程

在PLAN_TABLE实例中指定访问路径:

  1. 可选: 在SQL语句中添加QUERYNO子句
    以下查询包含一个QUERYNO子句的示例:
    SELECT * FROM T1
      WHERE C1 = 10 AND
            C2 BETWEEN 10 AND 20 AND
            C3 NOT LIKE 'A%'
      QUERYNO 100;
    在PLAN_TABLE实例中指定访问路径时,不需要执行此步骤。 然而,通过指定查询编号来识别每个SQL语句,可以消除PLAN_TABLE中行与SQL对应语句之间关系的模糊性。

    例如,动态应用程序的语句编号就是准备应用程序中语句的语句编号。 对于某些应用程序,例如 DSNTEP2 ,应用程序中的同一语句会生成每个动态语句,这意味着每个动态语句具有相同的语句编号。

    同样,当您修改包含静态语句的应用程序时,语句编号可能会发生变化,导致PLAN_TABLE中的行与修改后的应用程序不同步。 使用QUERYNO子句的语句不依赖于语句编号。 您可以移动这些语句,而不会影响 PLAN_TABLE 中行与应用程序中相应语句之间的关系。

    这种模棱两可的情况可能会导致 Db2 无法执行指定的访问路径。

  2. 在SQL语句的PLAN_TABLE行的OPTHINT列中为指定的访问路径输入一个名称。
    这一步使 Db2 能够识别指定访问路径的PLAN_TABLE行。
    UPDATE PLAN_TABLE
      SET OPTHINT = 'NOHYB'
      WHERE QUERYNO = 200 AND
            APPLNAME = ' ' AND
            PROGNAME = 'DSNTEP2' AND
            VERSION = ' ' AND
            COLLID = 'DSNTEP2';
  3. 可选: 修改PLAN_TABLE行,指示 Db2 尝试使用不同的访问路径
    您也可以在重新绑定或准备后,仅使用PLAN_TABLE访问路径来尝试强制使用相同的访问路径。 在这种情况下,您可以跳过此步骤。 但是,请记住,PLAN_TABLE访问路径并不是在重新绑定或准备后强制使用现有访问路径的推荐方法。 请在重新绑定时使用APREUSE选项,或者指定计划管理策略。

    例如,假设 Db2 选择了混合连接(METHOD = 4 ),而您知道排序合并连接(METHOD = 2 )可能效果更好。 您可以发布以下声明。

    UPDATE PLAN_TABLE
      SET METHOD = 2 
      WHERE QUERYNO = 200 AND
            APPLNAME = ' ' AND
            PROGNAME = 'DSNTEP2' AND
            VERSION = '' AND
            COLLID = 'DSNTEP2' AND
            OPTHINT = 'NOHYB' AND
            METHOD = 4;
    
  4. 请发送邮件至 Db2 ,开始执行指定的访问路径:
    选项 描述
    用于动态语句……
    1. 发出SET CURRENT OPTIMIZATION HINT = 'hint-name' 语句。
    2. 如果SET CURRENT OPTIMIZATION HINT语句是静态SQL语句,请重新绑定计划或包。
    3. 对使用访问路径的语句发布EXPLAIN语句。 Db2 为语句的规划表添加行,并将 “提示名称”值插入到HINT_USED列中。

    如果启用了动态语句缓存,则 Db2 仅在动态语句缓存中未找到匹配的语句时才尝试使用该提示。 否则, Db2 将使用缓存的计划,不准备报表,也不考虑指定的访问路径。

    对于静态语句…… 重新绑定包含语句的计划或包,并指定EXPLAIN(YES)和 OPTHINT('hint-name') 选项。
    Db2 在匹配指定SQL语句访问路径的行时,使用以下PLAN_TABLE列:
    • QUERYNO
    • APPLNAME
    • PROGNAME
    • 版本
    • COLLID
    • OPTHINT
    当您在PLAN_TABLE实例中指定访问路径时,最好为PLAN_TABLE创建一个索引。

    如果 Db2 使用了您指定的所有访问路径,则从EXPLAIN语句的PREPARE和SQL语句的PREPARE返回SQLCODE +394,这些语句使用了指定的访问路径。 如果指定的访问路径无效,或者发现任何重复,请发送电子邮件至 Db2 ,并附上SQLCODE +395。 通过设置SUPPRESS_HINT_SQLCODE_DYN子系统参数的值,可以禁止动态SQL语句中的SQLCODES +394和+395。

    如果 Db2 没有找到指定的访问路径,则会返回另一个SQLCODE。 通常情况下,SQLCODE为0。Db2 在绑定操作完成后还会返回一条消息,以识别完全应用、未应用、部分应用和未找到的语句数量。

  5. 从PLAN_TABLE中选择,检查 Db2 是否使用了指定的访问路径。
    例如,您可以发布以下声明:
    SELECT *
      FROM PLAN_TABLE
       WHERE QUERYNO = 200
      ORDER BY TIMESTAMP, QUERYNO, QBLOCKNO, PLANNO, MIXOPSEQ; 

    下表显示了PLAN_TABLE数据示例。 OPTHINT列包含指定访问路径的值NOHYB。 您还可以看到, Db2 使用了该访问路径,这由HINT_USED列中的NOHYB值指示。

    表 1. PLAN_TABLE显示使用了NOHYB访问路径。
    QUERYNO 方法 TNAME OPTHINTS HINT_USED
    200 0 EMP NOHYB
    200 2 EMPPROJACT NOHYB  
    200 3   NOHYB  
    200 0 EMP   NOHYB
    200 2 EMPPROJECT   NOHYB
    200 3     NOHYB
    结束特定程序编程接口信息。