如何在使用子查询返回的标量值时在 DB2 上强制使用索引?

How to force index usage on DB2 while using a scalar value returned by a subquery?

查询在巨大的 table(10 亿条记录 +)

上运行

Select Col1 from TableA where identcol > (select bigint(identval) from ParamTable)

identval 数据类型是字符,identcolBIGINT ) 这需要很长时间并进行完整的 table 扫描。当我替换子查询并在 identcol 的 where 子句中使用数字值时,它开始使用该列上的索引。

有没有办法强制 DB2 使用这个索引,而不用指定文字值? (AIX 上的 DB2 9.7 luw)

编辑:我发现 BETWEEN 使用子查询和上限值,还使用索引。此外,如果我删除对 BIGINT 的显式转换,它就会开始使用索引。但仍然想知道技术解释/指针。谢谢!

此行为可能是由于在没有文字值的情况下查询优化器可用的信息不足。

当在谓词中提供文字值时,优化器可以使用 tableA.identcol 的值分布统计信息来估计有多少行可能符合条件。显然,分配是这样的,给定提供的文字值,它认为基于索引的访问更好。

当您改为提供子查询时,优化器无法知道 identval 将返回什么,因此它会进行猜测,在您的情况下结果是次优的。

为了获得更一致的优化结果,您需要向优化器提供额外信息。您可以尝试几个选项。

  1. 创建一个统计视图,例如 create view sv1 as select Col1 from TableA, ParamTable where TableA.identcol > ParamTable.identval(并从您的查询中删除 bigint()——无需进一步混淆优化器)。然后您需要启用统计视图优化 (alter view sv1 enable query optimization) 并收集分布统计信息 (runstats on table sv1 with distribution)。但是,看到 ParamTable 中只有一行,人们可能会认为它更改得非常频繁,因此您需要确保每次 ParamTable.identval 更改时都会更新统计信息。
  2. 向优化器提供明确的选择性估计:Select Col1 from TableA where identcol > (select bigint(identval) from ParamTable) selectivity 0.001。在此之前,您需要设置启用此行为的 DB2 注册表变量 (db2set DB2_SELECTIVITY=ALL) 并重新启动实例。 0.001 表示 table 中满足条件的比例,在本例中为 0.1%。将 0.001 替换为匹配行比例的实际估计值。

  3. TableA (identcol, Col1) 上创建一个索引(如果它尚不存在)(并为其收集统计信息)——这可能启用仅索引访问。