数据库查询优化中的动态采样(Dynamic Sampling)与统计信息自动校正技术进阶
一、知识点描述
动态采样是数据库查询优化中的一项关键技术,主要用于解决统计信息缺失、过时或不准确导致的查询计划选择错误问题。传统数据库依赖预收集的统计信息(如行数、唯一值数量、数据分布直方图等)来估算查询成本。但在以下场景中,静态统计信息可能失效:
- 统计信息缺失:新建表、中间临时表、未收集统计信息的表。
- 统计信息过时:表数据被大量插入、删除、更新后,统计信息未及时刷新。
- 复杂谓词估算不准:涉及多个列的条件、复杂表达式、关联子查询等,静态统计信息模型难以准确估算选择率。
- 绑定变量窥探问题:使用绑定变量时,优化器可能基于首次传入的参数生成计划,不适用于后续不同参数值。
动态采样通过在查询编译阶段,临时对表数据进行小范围随机采样,快速估算出更准确的基数(行数),从而辅助优化器选择更优的执行计划。本专题将深入讲解其工作原理、触发机制、采样算法、与自动校正的协同,以及潜在代价。
二、解题过程/技术原理解析
步骤1:识别统计信息缺陷场景
优化器在生成查询计划前,会评估可用统计信息的质量。动态采样通常在以下情况被触发(以Oracle/PostgreSQL为例):
- 查询涉及的对象(表、物化视图)没有可用的统计信息。
- 优化器检测到谓词条件复杂,现有直方图无法提供可靠的选择率估算。
- 查询涉及多列关联,但缺乏扩展统计信息(Extended Statistics)。
- 系统参数设置(如Oracle的
OPTIMIZER_DYNAMIC_SAMPLING级别)指示在特定情况下启用。
步骤2:确定采样级别与采样目标
数据库允许设置动态采样的级别(通常为0-10级),控制其积极程度:
- 级别0:禁用动态采样。
- 级别1:仅当表无统计信息且满足某些条件(如索引访问)时采样。
- 级别2-4:对无统计信息的表进行更积极的采样,样本量增加。
- 级别5-10:即使有统计信息,若优化器认为估算可能不准(如复杂WHERE子句),也会触发采样。级别越高,采样块数越多,估算越准,但编译时间也越长。
采样目标通常是估算特定查询片段的基数,例如某个表的过滤后行数,或某个连接操作的中间结果大小。
步骤3:执行动态采样操作
当决定采样后,优化器在查询编译阶段执行以下操作:
- 选择采样方法:通常采用随机块采样。数据库从磁盘或缓冲区中随机选取数据块(例如,采样级别为2时可能采样32个块),而不是全表扫描,以最小化I/O开销。
- 解析谓词并应用:对采样到的数据块中的每一行,应用查询中的相关过滤条件(WHERE子句、连接条件),统计满足条件的行数。
- 计算估算基数:基于采样统计,推算全表的基数。公式一般为:
估算基数 = (采样块中满足条件的行数 / 采样块的总行数) * 全表估算总行数
其中,全表估算总行数可能来自段统计(高水位块数估算),若表无任何统计,则也基于采样推算。
步骤4:基于采样结果优化查询计划
优化器将动态采样得到的基数估算值,代入其代价模型:
- 重新评估访问路径:例如,一个筛选条件,静态统计认为返回90%的行,导致选择全表扫描;但动态采样发现实际只返回1%的行,可能改为使用索引扫描。
- 调整连接顺序与算法:连接操作的中间结果大小估算更准确后,优化器可能选择不同的连接顺序(如小表驱动大表)或连接算法(Nested Loop Join改为Hash Join)。
- 确定并行度:对于并行查询,更准确的基数有助于分配合适的并行进程数,避免资源浪费或不足。
步骤5:统计信息自动校正与反馈循环
高级的动态采样技术会与统计信息反馈机制结合,形成闭环优化:
- 执行时监控:查询实际执行时,执行引擎会记录实际返回的行数(实际基数)。
- 对比与检测偏差:将实际基数与优化器估算基数比较。如果偏差超过阈值(例如,Oracle中可能为2倍),则标记该查询计划中的相关估算为“不准确”。
- 反馈存储:将不准确的信息(如表、列、谓词表达式及实际基数)存储到数据字典或特定缓存中。
- 后续查询校正:当下次编译相同或类似查询时,优化器会先检查反馈存储。如果发现历史校正数据,则优先使用该数据来校正基数估算,可能因此生成不同的计划。这可以避免对相同模式查询重复进行动态采样,直接复用历史经验。
- 触发统计信息重新收集:系统可能自动安排作业,在后台重新收集相关对象的完整统计信息,从根本上解决信息过时问题。
步骤6:权衡采样成本与收益
动态采样不是“免费”的,其核心权衡在于:
- 收益:获得更准确的基数估算,从而选择更优执行计划,大幅降低查询执行时间(尤其对于复杂分析型查询)。
- 成本:增加了查询的编译时间,因为需要额外的I/O和CPU来读取和扫描采样块。对于短小频繁的OLTP查询,采样成本可能抵消甚至超过计划优化带来的收益。
因此,实践中需要合理配置采样级别,通常建议:
- 对数据仓库、报表系统等OLAP环境,可设置较高级别(如5-8),因为查询复杂,执行时间长,采样带来的计划改进收益大。
- 对OLTP系统,设置较低级别(如2-3),主要应对无统计信息表,避免影响高频短查询的编译速度。
三、总结与对比
动态采样是优化器在“信息不完全”情况下的一种自适应和补偿机制。它像是一个实时调查员,在需要时快速抽样获取数据特征,以做出更佳决策。与传统静态统计信息相比:
- 静态统计:定期、全局、成本高、可能过时,但一次收集可重复使用。
- 动态采样:按需、局部、快速、针对性强,但增加单次编译开销。
将其与统计信息反馈结合,形成了“动态采样(短期校正) + 反馈学习(中期复用) + 自动收集(长期根治)”的三层优化体系,显著提升了复杂、动态变化数据环境下的查询优化鲁棒性。
核心要点:动态采样通过在查询编译时进行小范围数据抽样,快速校正基数估算,从而帮助优化器选择更准确的执行计划,尤其适用于统计信息缺失或过时的场景。其高级形态与执行反馈机制集成,实现了持续的学习和优化。