在Oracle数据库的性能问题排查中,执行计划走偏是很常见的一类故障。明明表上有索引,优化器却选择全表扫描;明明只有几千行符合条件的记录,估算的基数却显示上百万。这些现象背后,往往和统计信息的准确性有关。当统计信息缺失、过期,或者查询涉及临时表、多列过滤条件时,Oracle优化器会依赖动态采样来补充估算依据。而控制这个行为的核心参数,就是OPTIMIZER_DYNAMIC_SAMPLING。

动态采样的工作原理与触发条件
动态采样(Dynamic Sampling)是CBO(基于成本的优化器)的一种辅助手段。它的基本思路是:在SQL硬解析阶段,优化器对目标表抽取一小部分数据块,快速扫描后根据这些数据估算出谓词的选择率、行的分布情况,再把这些临时统计信息用于执行计划的成本计算。整个过程发生在解析阶段,而不是执行阶段,这一点是理解它性能影响的关键。
优化器并不是对所有SQL都做动态采样,它的触发有一套判断逻辑。当表没有收集过统计信息时,动态采样会被自动激活;当查询中的谓词涉及多列组合,而列级统计信息无法准确描述相关性时,较高等级的动态采样会介入;当查询包含复杂表达式、函数或取样无法覆盖的过滤条件时,也是动态采样的用武之地。换句话说,动态采样本质上是统计信息的补丁,它解决的是优化器看不到真实数据分布的问题。
需要注意,动态采样是消耗资源的。采样需要真实读取数据块,如果表很大、等级又高,采样读取的块数会显著增加,硬解析时间随之变长。对于高并发、短SQL密集的系统,这种开销需要谨慎评估。
OPTIMIZER_DYNAMIC_SAMPLING各等级含义详解
该参数取值范围是0到10,默认值为2。不同等级的核心差异体现在两个维度:一是优化器判定是否使用动态采样的条件宽严程度,二是实际采样的数据块规模。下面逐级说明。
等级0表示禁用动态采样,优化器完全依赖已有的统计信息,哪怕这些信息是缺失的。等级1是较保守的设置,优化器只在没有统计信息的表上做采样,且默认只采样32个块,同时如果表上存在单表谓词并且没有统计信息,也会触发。等级2是Oracle的默认值,对所有未分析过的表进行采样,块数同样为32,它比等级1的覆盖面更广一些。
从等级3开始,采样的触发条件扩展到了带有选择率估算的谓词。等级3会对所有满足条件的查询做采样以验证选择率,等级4则引入了多列谓词的采样(比如WHERE a = 1 AND b = 2这种跨列条件),等级5在等级4的基础上使用两倍的块数。等级6继续用两倍策略,覆盖单表谓词的所有表,等级7到9则不断加大采样块规模(从64、128到256块),让估算精度进一步提升。等级10是全量读取级别,采样会读取表的所有块,估算最精确,但代价也最大,除非表很小,否则一般不建议生产环境使用。
可以用下面这条SQL快速查看当前设置:
-- 查看参数当前值 SELECT name, value, isdefault FROM v$parameter WHERE name = 'optimizer_dynamic_sampling'; -- 会话级别修改为等级4 ALTER SESSION SET optimizer_dynamic_sampling = 4; -- 系统级别修改 ALTER SYSTEM SET optimizer_dynamic_sampling = 4 SCOPE = BOTH;
生产环境中的设置建议与常见误区
设置这个参数时,第一个原则是先保证统计信息本身是准确的。动态采样只是兜底手段,如果定时任务维护得当,绝大多数表的估算问题应该通过DBMS_STATS解决,而不是靠抬高采样等级。把等级当万能药的思路,容易掩盖统计信息维护机制的缺陷。
对于有明确场景的系统,可以针对性调整。典型例子是ETL过程中的全局临时表(GTT)和中间结果表,这些表往往没有持久统计信息,把会话级别的动态采样设为4或6,配合DBMS_STATS.SET_TABLE_PREFS为特定表固定采样等级,效果比全局抬高参数好得多。报表类系统SQL解析频率低、单条SQL执行时间长,可以接受较高等级带来的解析开销;而OLTP高并发系统则建议保持默认等级2,避免硬解析被采样拖慢。
常见的误区有两个。一是无脑设成10追求估算精确,结果硬解析时间暴涨,短SQL密集的会话被拖垮,这是典型的得不偿失。二是版本差异带来的认知偏差:从Oracle 12c开始引入了自适应统计信息(OPTIMIZER_ADAPTIVE_STATISTICS),部分动态采样功能被新的机制取代,11g中调等级的经验不能直接照搬到更高版本,升级后应重新评估。定位问题时,可以通过执行计划中的NOTE部分确认是否使用了动态采样,输出类似dynamic sampling used for this statement (level=4)的提示,就能判断实际生效的等级。
总结来说,OPTIMIZER_DYNAMIC_SAMPLING的等级选择本质是估算精度与解析开销之间的权衡。默认等级2适合大多数场景,遇到临时表、多列相关、统计信息缺失等具体情况时,优先在表级别或会话级别精细化设置,而不是粗暴修改全局参数。先修统计信息,再用动态采样兜底,才是稳定的调优路径。
OPTIMIZER_DYNAMIC_SAMPLINGOracle优化器动态采样修改时间:2026-09-11 12:40:31