在 DB2 中,LIKE 谓词的基数估计一直是影响 SQL 执行计划质量的关键环节。优化器在没有足够统计信息时,往往使用固定选择性猜测,这会让执行计划完全偏离实际数据分布。opt_like_stats 参数就是为解决这一问题而设计的优化开关,它能让优化器更聪明地估算 LIKE 表达式的返回行数,从而选择更优的索引和连接顺序。

为什么 LIKE 谓词会导致统计失真
传统上,DB2 优化器对 LIKE 谓词的选择性估算采用一套简单的假设规则。例如,对于形如 column LIKE 'value%' 的前缀匹配,优化器可能统一假定返回总行数的某个固定百分比;而对于 column LIKE '%value%' 这种前后都有通配符的模式,它可能直接沿用更保守的估算。这种方式在列数据均匀分布时勉强可用,但如果列数据存在严重倾斜,估算值与实际返回行数可能相差一到两个数量级。
更麻烦的是,LIKE 谓词中的通配符位置会显著改变实际匹配范围。'ABC%' 可以较好地利用普通索引进行范围扫描,而 '%ABC%' 通常无法使用索引前缀,必须走全索引扫描或全表扫描。如果优化器无法感知模式差异和数据分布,就可能在索引范围扫描与全表扫描之间做出错误选择。一个典型场景是:某个状态列中 90% 的值以 'active' 开头,查询条件却是 LIKE 'in%',实际匹配可能只有几十行,但固定选择性假设可能估成几十万行,最终错误地选择全表扫描。
此外,LIKE 谓词还经常出现在模糊搜索、日志分析、用户输入过滤等场景中。这些场景的查询往往带有通配符且列值分布高度不均匀,优化器如果继续沿用固定假设,就会导致大量 SQL 语句的执行计划失准。正是这一系列问题,促使 DB2 引入 opt_like_stats 参数来提升 LIKE 统计信息的利用率。
opt_like_stats 的作用机制与启用方法
opt_like_stats 是 DB2 提供的一项优化器参数,默认处于关闭状态。当该参数启用后,优化器在处理 LIKE 谓词时,不再只依赖固定的选择性假设,而是会结合列上的分布统计信息以及 LIKE 模式的通配符位置,进行更细粒度的基数估算。例如,对于前缀匹配,优化器可以通过列分布数据估算该前缀在实际数据中的出现频率;对于包含通配符的复杂模式,也会根据模式长度和通配符位置做出更接近真实的判断。
启用方式分为数据库级和实例级两种。数据库级通过 UPDATE DB CFG 命令设置,只对特定数据库生效,适合精细控制:
-- 在数据库 sample 上启用 opt_like_stats UPDATE DB CFG FOR sample USING opt_like_stats YES;
实例级则通过设置注册表变量 DB2_OPTLIKE_STATS 实现,对所有数据库生效:
db2set DB2_OPTLIKE_STATS=YES db2stop db2start
两者可以同时存在,但数据库配置参数的优先级高于注册表变量。启用参数后,还必须保证相关列拥有足够新的分布统计信息。建议使用 RUNSTATS 命令重新收集统计,并添加 WITH DISTRIBUTION 选项:
RUNSTATS ON TABLE myschema.mytable WITH DISTRIBUTION AND DETAILED INDEXES ALL;
需要注意的是,仅仅打开优化开关并不会自动生成统计信息,已有的旧统计也无法反映当前数据分布。如果跳过 RUNSTATS 步骤,opt_like_stats 可能仍然缺少可用的高精度数据,优化效果会大打折扣。因此,启用参数与更新统计信息应当作为一个完整的优化流程来执行。
实际效果验证与使用注意事项
以一个订单表为例,假设 ORDERS 表包含约 2000 万行数据,其中 CUST_NAME 列的数据分布极不均匀,以字母 'Z' 开头的客户名实际只有几百行,但在未启用 opt_like_stats 之前,查询 WHERE CUST_NAME LIKE 'Z%' 时优化器可能将其估算为数十万行,从而选择了全表扫描。启用 opt_like_stats 并重新收集分布统计后,优化器对 'Z%' 的选择性估算变得非常接近实际值,最终选择了基于 CUST_NAME 索引的范围扫描,查询响应时间从秒级下降到毫秒级。
这类改善在存在大量 LIKE 前缀查询的在线交易系统或数据仓库中尤为明显。特别是当表数据量较大且列倾斜严重时,opt_like_stats 带来的基数估算修正可以避免大量不必要的全表扫描,间接降低 I/O 压力和 CPU 消耗。不过,由于统计信息的计算需要额外分析列分布,启用该参数会增加 SQL 语句的编译时间。对于查询频率较低、表数据量较小的场景,这部分额外开销可能并不划算。
使用 opt_like_stats 还应注意统计信息的维护频率。数据分布变化较快时,需要定期执行 RUNSTATS 以保持统计的新鲜度,否则优化器可能会依据过期的分布数据做出新的错误估算。建议在测试环境中先行验证,对比启用前后的执行计划、编译时间以及包缓存效果,确认对目标工作负载确实有益后再推广到生产环境。对于以 LIKE 模糊搜索为核心的查询负载,这一参数往往能带来明显的执行计划改善。
DB2 opt_like_statsLIKE查询优化统计信息修改时间:2026-09-18 01:59:33