首批通过分布式安全可靠测评,为关键业务系统打造
动态采样的工作原理与实践
更新时间:2026-05-14 09:21
OceanBase 数据库 V4.2.0 版本开始支持优化器动态采样功能,该功能在 SQL 运行时动态收集统计信息,帮助优化器生成更好的执行计划,从而优化查询性能。OceanBase 数据库的 SQL 查询语句都会自动应用动态采样功能,使计划的生成更加精准,执行计划的执行更加高效。
详细说明
动态采样的工作原理
数据库优化器在为 SQL 生成执行计划时,主动对表数据进行动态的采样,以生成所需要的统计信息,从而能够更加准确地估算查询条件的选择率以及执行计划的代价,选出更好的执行计划。
动态采样的应用场景
动态采样功能需要在生成执行计划时访问数据进行采样,无移会增加执行计划生成的耗时,因此仅适用于执行时间较长、执行计划选择不佳的复杂查询、大数据量查询的场景。
OceanBase 数据库当前只支持基表的动态采样。在没有关闭动态采样功能时,以下场景会尝试在计划生成阶段使用动态采样:
没有统计信息的场景。
查询条件中存在复杂谓词的场景,例如
c1 like '%test%',无法用选择率计算公式进行行数估计。用户通过 Hint 等方式指定使用动态采样的场景。
动态采样的控制方法
OceanBase 数据库支持使用系统变量、查询 Hint 及系统配置项三种方式进行动态采样功能的控制,同时动态采样的采样集大小受限于并行度的控制。
详细内容请参见:优化器动态采样。
查询使用了动态采样的判断
使用 EXPLAIN EXTENDED 命令查看 SQL 的执行计划,Optimization Info 中的 estimation method 表明了优化器获取统计信息的途径,如果途径为 DYNAMIC SAMPLING,则表示优化器使用了动态采样功能。
-- 没有统计信息,尝试动态采样
obclient [TEST]> explain extended select * from t_part where c1 > 1;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ============================================================= |
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| ------------------------------------------------------------- |
| |0 |PX COORDINATOR | |9960 |29434 | |
| |1 |└─EXCHANGE OUT DISTR |:EX10000|9960 |20651 | |
| |2 | └─PX PARTITION ITERATOR| |9960 |907 | |
| |3 | └─TABLE FULL SCAN |T_PART |9960 |907 | |
| ============================================================= |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([INTERNAL_FUNCTION(T_PART.C1(0x7f5fd0c20c90), T_PART.C2(0x7f5fd0c22010), T_PART.C3(0x7f5fd0c22330))(0x7f5fd0cab130)]), filter(nil), rowset=256 |
| 1 - output([INTERNAL_FUNCTION(T_PART.C1(0x7f5fd0c20c90), T_PART.C2(0x7f5fd0c22010), T_PART.C3(0x7f5fd0c22330))(0x7f5fd0cab130)]), filter(nil), rowset=256 |
| dop=1 |
| 2 - output([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), filter(nil), rowset=256 |
| force partition granule |
| 3 - output([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), filter([T_PART.C1(0x7f5fd0c20c90) > 1(0x7f5fd0c21600)]), rowset=256 |
| access([T_PART.C1(0x7f5fd0c20c90)], [T_PART.C2(0x7f5fd0c22010)], [T_PART.C3(0x7f5fd0c22330)]), partitions(p[0-3]) |
| is_index_back=false, is_global_index=false, filter_before_indexback[false], |
| range_key([T_PART.__pk_increment(0x7f5fd0c22a20)]), range(MIN ; MAX)always true |
| Used Hint: |
| ------------------------------------- |
| /*+ |
| |
| */ |
| Qb name trace: |
| ------------------------------------- |
| stmt_id:0, stmt_type:T_EXPLAIN |
| stmt_id:1, SEL$1 |
| Outline Data: |
| ------------------------------------- |
| /*+ |
| BEGIN_OUTLINE_DATA |
| FULL(@"SEL$1" "TEST"."T_PART"@"SEL$1") |
| PARALLEL( AUTO ) |
| OPTIMIZER_FEATURES_ENABLE('4.2.4.0') |
| END_OUTLINE_DATA |
| */ |
| Optimization Info: |
| ------------------------------------- |
| T_PART: |
| table_rows:10000 |
| physical_range_rows:10000 |
| logical_range_rows:10000 |
| index_back_rows:0 |
| output_rows:9960 |
| table_dop:1 |
| dop_method:Auto DOP |
| avaiable_index_name:[T_PART] |
| stats info:[version=0, is_locked=0, is_expired=0] |
| dynamic sampling level:1 |
| estimation method:[DYNAMIC SAMPLING FULL] |
| Plan Type: |
| DISTRIBUTED |
| Note: |
| Degree of Parallelisim is 1 because of Auto DOP |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
动态采样的使用建议
OceanBase 数据库的动态采样功能主要解决因统计信息缺失以及复杂谓词条件导致的估算不准的问题,但无法应对统计信息失效的场景。当系统中存在数据量特别大的表且大表上存在频繁的 DML 操作时,如果自动统计信息收集任务不能在限定的时间窗口内完成大表的统计信息更新,则需要使用 Hint 等手段为大查询主动开启动态采样功能。
SELECT /*+DYNAMIC_SAMPLING(t1 1)*/ c4 FROM t1 WHERE c1 > 1 AND c2 > 1 AND c3 > 1 GROUP BY c4;
而在以简单查询、索引访问为主的 TP 场景,为了避免因为 SQL 语句中的复杂谓词而触发动态采样、增加 SQL 执行的耗时,则可以通过系统变量在系统层面关闭动态采样功能,只对有特殊需要的 SQL 语句使用 Hint。
## 关闭动态采样,优化器使用默认统计信息
SET GLOBAL optimizer_dynamic_sampling = 0;
适用版本
OceanBase 数据库 V4.2.x、V4.3.x 版本。