操作指导
前置条件
- 数据库运行正常。
- 反馈基数功能开启。
- 数据库查询解析正常进入计划优化阶段。
使用指导
打开参数enable_adaptive_cost,其他参数使用默认设置即可开启本功能。
反馈基数功能需要先收集基数才能修正统计偏差,只有通过explain (analyze)执行或执行时间超过adaptive_cost_min_time的SQL才会收集基数信息。
当设置adaptive_cardest_strategy=auto(默认配置)时,同类型的SQL(按照sql id区分)第一次执行不会使用反馈基数。对重复执行的同类SQL,会按照过去的执行时间来判断是否可以使用反馈基数。如果出现了严重的计划劣化,即本次执行时间超过了不使用反馈基数平均执行时间的10倍再多5秒,则会将对应的SQL列入黑名单,不再使用反馈基数。例如,某sql不使用反馈基数的平均执行时间为1s,如果使用反馈基数后执行时间超过了1*10+5=15秒,则会列入黑名单。
示例
受环境、版本及部署形态差异影响,示例中的执行计划可能与实际不同。本示例仅作为参考,具体优化效果请以实际执行计划为准。
- 通过后台线程自动进行模型训练,调整执行计划。
- 启动数据库,查看enable_adaptive_cost参数是否开启,确保反馈基数估计功能的后台训练已正常开启。
gaussdb=# SHOW enable_adaptive_cost; enable_adaptive_cost ---------------------- on (1 row) - 设置计划展示格式。
gaussdb=# SET explain_perf_mode = pretty; - 执行由于错误的基数估计导致次优计划的语句,如含有多种连接路径和连接类型的查询SQL,观察执行计划在多次执行中是否迭代出更优计划。以JOB数据集为例,首先导入JOB数据集,并运行查询语句01b.sql。
gaussdb=# EXPLAIN (ANALYZE) SELECT MIN(mc.note) AS production_note, MIN(t.title) AS movie_title, MIN(t.production_year) AS movie_year FROM company_type AS ct, info_type AS it, movie_companies AS mc, movie_info_idx AS mi_idx, title AS t WHERE ct.kind = 'production companies' AND it.info = 'bottom 10 rank' AND mc.note NOT LIKE '%(as Metro-Goldwyn-Mayer Pictures)%' AND t.production_year BETWEEN 2003 AND 2010 AND ct.id = mc.company_type_id AND t.id = mc.movie_id AND t.id = mi_idx.movie_id AND mc.movie_id = mi_idx.movie_id AND it.id = mi_idx.info_type_id; - 观察执行计划可知,总执行时间为1442.612毫秒。重点关注A-rows(实际行数)与E-rows(估计行数)两列数据,可以发现当前计划生成过程中的基数估计存在显著偏差。例如,对于Hash Join(5, 11)算子,其实际行数仅为4行,而估计行数却高达528329行。正是由于此类基数估计偏差,导致该执行计划并非当前最优选择。此时,因后台训练功能已开启,反馈基数估计模块的后台训练线程将被触发,自动执行模型训练任务。
id | operation | A-time | A-rows | E-rows | Peak Memory | E-memory | A-width | E-width | E-costs ----+---------------------------------------------------------------------------------------+---------------------+---------+---------+---------------+----------+---------+---------+----------- 1 | -> Aggregate | 1442.612 | 1 | 1 | 29KB | | | 113 | 107165.90 2 | -> Streaming (type: GATHER) | 1442.467 | 3 | 3 | 150KB | | | 113 | 107165.90 3 | -> Aggregate | [1382.897,1422.194] | 3 | 3 | [27KB,28KB] | 1MB | | 113 | 107165.78 4 | -> Hash Join (5,11) | [1382.845,1422.167] | 4 | 528329 | [10KB,10KB] | 1MB | | 45 | 105844.94 5 | -> Streaming(type: REDISTRIBUTE) | [435.768,481.418] | 140904 | 1303008 | [69KB,69KB] | 2MB | | 28 | 55550.75 6 | -> Nested Loop (7,9) | [495.739,559.512] | 140904 | 1303008 | [4KB,4KB] | 1MB | | 28 | 19718.03 7 | -> Streaming(type: BROADCAST) | [0.063,33.318] | 3 | 3 | [45KB,45KB] | 2MB | | 4 | 2.30 8 | -> Seq Scan on company_type ct | [0.003,0.074] | 1 | 1 | [32KB,32KB] | 1MB | | 4 | 2.02 9 | -> Bitmap Heap Scan on movie_companies mc | [475.771,539.464] | 140904 | 1303008 | [74KB,76KB] | 1MB | | 32 | 15372.37 10 | -> Bitmap Index Scan using company_type_id_movie_companies | [120.751,130.875] | 1334883 | 1304564 | [356KB,356KB] | 1MB | | 0 | 3495.96 11 | -> Hash | [833.688,891.113] | 6 | 407937 | [2MB,2MB] | 16MB | [48,52] | 29 | 44769.35 12 | -> Hash Join (13,14) | [833.646,891.058] | 6 | 407937 | [11KB,11KB] | 1MB | | 29 | 44769.35 13 | -> Seq Scan on title t | [704.619,725.190] | 868629 | 872254 | [52KB,52KB] | 1MB | | 25 | 24237.56 14 | -> Hash | [13.300,84.206] | 10 | 345009 | [1MB,1MB] | 16MB | [20,20] | 4 | 15190.38 15 | -> Streaming(type: REDISTRIBUTE) | [13.221,84.122] | 10 | 345009 | [45KB,45KB] | 2MB | | 4 | 15190.38 16 | -> Nested Loop (17,19) | [10.662,46.745] | 10 | 345009 | [3KB,3KB] | 1MB | | 4 | 5702.64 17 | -> Streaming(type: BROADCAST) | [10.177,46.329] | 3 | 3 | [45KB,45KB] | 2MB | | 4 | 1.75 18 | -> Seq Scan on info_type it | [0.271,0.349] | 1 | 1 | [32KB,32KB] | 1MB | | 4 | 1.48 19 | -> Bitmap Heap Scan on movie_info_idx mi_idx | [0.210,0.376] | 10 | 345009 | [23KB,24KB] | 1MB | | 8 | 4550.86 20 | -> Bitmap Index Scan using info_type_id_movie_info_idx | [0.160,0.271] | 10 | 345009 | [3KB,3KB] | 1MB | | 0 | 926.57 (20 rows)
- 再次执行查询并观察执行计划,可见执行时间已优化(从6763.152毫秒降至5337.537毫秒)。分析基数估计情况,在反馈基数估计模型的预测下,多数算子的基数估计值得到了有效矫正,从而优化了执行计划的生成。
gaussdb=# EXPLAIN (ANALYZE) SELECT MIN(mc.note) AS production_note, MIN(t.title) AS movie_title, MIN(t.production_year) AS movie_year FROM company_type AS ct, info_type AS it, movie_companies AS mc, movie_info_idx AS mi_idx, title AS t WHERE ct.kind = 'production companies' AND it.info = 'bottom 10 rank' AND mc.note NOT LIKE '%(as Metro-Goldwyn-Mayer Pictures)%' AND t.production_year BETWEEN 2003 AND 2010 AND ct.id = mc.company_type_id AND t.id = mc.movie_id AND t.id = mi_idx.movie_id AND mc.movie_id = mi_idx.movie_id AND it.id = mi_idx.info_type_id; id | operation | A-time | A-rows | E-rows | Peak Memory | E-memory | A-width | E-width | E-costs ----+------------------------------------------------------------------------------------------+-----------------+--------+--------+-------------+----------+---------+---------+--------- 1 | -> Aggregate | 72.986 | 1 | 1 | 29KB | | | 113 | 5858.87 2 | -> Streaming (type: GATHER) | 72.860 | 3 | 3 | 150KB | | | 113 | 5858.87 3 | -> Aggregate | [55.949,56.995] | 3 | 3 | [26KB,27KB] | 1MB | | 113 | 5858.74 4 | -> Nested Loop (5,7) | [55.815,56.920] | 4 | 57132 | [8KB,8KB] | 1MB | | 45 | 5715.90 5 | -> Streaming(type: BROADCAST) | [0.099,0.197] | 3 | 3 | [45KB,45KB] | 2MB | | 4 | 2.30 6 | -> Seq Scan on company_type ct | [0.001,0.038] | 1 | 1 | [32KB,32KB] | 1MB | | 4 | 2.02 7 | -> Materialize | [55.498,56.637] | 81 | 19 | [14KB,18KB] | 16MB | | 49 | 5713.55 8 | -> Nested Loop (9,18) | [55.427,56.565] | 78 | 19 | [9KB,9KB] | 1MB | | 49 | 5713.53 9 | -> Streaming(type: BROADCAST) | [53.757,54.850] | 18 | 36 | [46KB,46KB] | 2MB | | 29 | 5705.90 10 | -> Nested Loop (11,17) | [38.080,44.807] | 6 | 12 | [6KB,6KB] | 1MB | | 29 | 5704.81 11 | -> Streaming(type: REDISTRIBUTE) | [37.643,43.903] | 10 | 10 | [45KB,45KB] | 2MB | | 4 | 5702.88 12 | -> Nested Loop (13,15) | [0.237,37.279] | 10 | 10 | [3KB,3KB] | 1MB | | 4 | 5702.64 13 | -> Streaming(type: BROADCAST) | [0.074,37.080] | 3 | 3 | [45KB,45KB] | 2MB | | 4 | 1.75 14 | -> Seq Scan on info_type it | [0.080,0.153] | 1 | 1 | [32KB,32KB] | 1MB | | 4 | 1.48 15 | -> Bitmap Heap Scan on movie_info_idx mi_idx | [0.113,0.138] | 10 | 345009 | [23KB,24KB] | 1MB | | 8 | 4550.86 16 | -> Bitmap Index Scan using info_type_id_movie_info_idx | [0.039,0.071] | 10 | 345009 | [3KB,3KB] | 1MB | | 0 | 926.57 17 | -> Index Scan using title_pkey on title t | [0.310,0.761] | 6 | 1 | [26KB,26KB] | 1MB | | 25 | 0.63 18 | -> Index Scan using movie_id_movie_companies on movie_companies mc | [0.791,1.698] | 78 | 2 | [16KB,16KB] | 1MB | | 32 | 0.62 (18 rows)
- 通过EXPLAIN ADAPTCOST选项展示模型使用情况,沿用上一节的执行计划。
- 设置计划展示格式,展示模型使用情况仅支持normal模式。
gaussdb=# SET explain_perf_mode = normal; - 在EXPLAIN语句中加入ADAPTCOST选项,执行查询。
gaussdb=# EXPLAIN (ANALYZE, ADAPTCOST) SELECT MIN(mc.note) AS production_note, MIN(t.title) AS movie_title, MIN(t.production_year) AS movie_year FROM company_type AS ct, info_type AS it, movie_companies AS mc, movie_info_idx AS mi_idx, title AS t WHERE ct.kind = 'production companies' AND it.info = 'bottom 10 rank' AND mc.note NOT LIKE '%(as Metro-Goldwyn-Mayer Pictures)%' AND t.production_year BETWEEN 2003 AND 2010 AND ct.id = mc.company_type_id AND t.id = mc.movie_id AND t.id = mi_idx.movie_id AND mc.movie_id = mi_idx.movie_id AND it.id = mi_idx.info_type_id; - 观察执行计划输出,可见在算子详情中新增了cardest字段。当算子应用了反馈基数估计模型进行基数预测时,该字段会显示所加载的模型名称。如第三个算子(Nested Loop)所示,其cardest字段值为UMM_S_3988043888,17038.5。这表明该算子使用了名为此标识符的UMM模型进行预测。模型名称即为该算子特征值(哈希值)。
QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------- Aggregate (cost=5711.89..5711.96 rows=1 cardest=default width=113) (actual time=98.249..98.250 rows=1 loops=1) -> Streaming (type: GATHER) (cost=5711.89..5711.96 rows=3 cardest=default width=113) (actual time=96.016..98.148 rows=3 loops=1) Node/s: All datanodes -> Aggregate (cost=5711.83..5711.84 rows=3 cardest=default width=113) (actual time=[49.865,49.866]..[88.874,88.874], rows=3) -> Nested Loop (cost=955.32..5711.82 rows=4 cardest=trust UMM_S_3988043888,17038.5 width=45) (actual time=[49.777,49.812]..[88.842,88.842], rows=4) Join Filter: (mc.company_type_id = ct.id), (Expression Flatten Optimized) Rows Removed by Join Filter: 74 -> Streaming(type: BROADCAST) (cost=0.00..2.30 rows=3 cardest=default width=4) (actual time=[0.070,0.075]..[0.099,0.105], rows=3) Spawn on: All datanodes -> Seq Scan on company_type ct (cost=0.00..2.02 rows=1 cardest=try default width=4) (actual time=[0.002,0.002]..[0.050,0.052], rows=1) Filter: ((kind)::text = 'production companies'::text), (Expression Flatten Optimized) Rows Removed by Filter: 3 -> Materialize (cost=955.32..5709.24 rows=84 cardest=default width=49) (actual time=[49.590,49.594]..[88.547,88.555], rows=81) -> Nested Loop (cost=955.32..5709.17 rows=84 cardest=trust UMM_S_229582469,17038.5(mixed) width=49) (actual time=[49.097,49.510]..[87.876,88.476], rows=78) Join Filter: (t.id = mc.movie_id), (Expression Flatten Optimized) -> Streaming(type: BROADCAST) (cost=955.32..5705.36 rows=18 cardest=default width=29) (actual time=[48.944,48.971]..[87.581,87.619], rows=18) Spawn on: All datanodes -> Nested Loop (cost=955.32..5704.81 rows=6 cardest=trust UMM_S_550930755,17038.5(mixed) width=29) (actual time=[0.227,30.510]..[77.161,77.197], rows=6) -> Streaming(type: REDISTRIBUTE) (cost=955.32..5702.88 rows=10 cardest=default width=4) (actual time=[0.073,30.357]..[76.971,76.982], rows=10) Spawn on: All datanodes -> Nested Loop (cost=955.32..5702.64 rows=10 cardest=trust UMM_F_1223820966(mixed) width=4) (actual time=[0.188,0.985]..[34.022,73.538], row s=10) -> Streaming(type: BROADCAST) (cost=0.00..1.75 rows=3 cardest=default width=4) (actual time=[0.074,0.867]..[33.869,73.378], rows=3) Spawn on: All datanodes -> Seq Scan on info_type it (cost=0.00..1.48 rows=1 cardest=try default width=4) (actual time=[0.062,0.064]..[0.077,0.077], rows =1) Filter: ((info)::text = 'bottom 10 rank'::text), (Expression Flatten Optimized) Rows Removed by Filter: 112 -> Bitmap Heap Scan on movie_info_idx mi_idx (cost=955.32..4550.86 rows=345009 cardest=default width=8) (actual time=[0.067,0.068]..[0 .093,0.097], rows=10) Recheck Cond: (info_type_id = it.id), (Expression Flatten Optimized) -> Bitmap Index Scan on info_type_id_movie_info_idx (cost=0.00..926.57 rows=345009 cardest=default width=0) (actual time=[0.034, 0.034]..[0.047,0.047], rows=10) Index Cond: (info_type_id = it.id) -> Index Scan using title_pkey on title t (cost=0.00..0.63 rows=1 cardest=try default width=25) (actual time=[0.107,0.107]..[0.215,0.215], rows=6) Index Cond: (id = mi_idx.movie_id) Filter: ((production_year >= 2003) AND (production_year <= 2010)) Rows Removed by Filter: 4 -> Index Scan using movie_id_movie_companies on movie_companies mc (cost=0.00..0.62 rows=2 cardest=try default width=32) (actual time=[0.248,0.402]..[0.336,0. 632], rows=78) Index Cond: (movie_id = mi_idx.movie_id) Filter: (note !~~ '%(as Metro-Goldwyn-Mayer Pictures)%'::text) Rows Removed by Filter: 15 Total runtime: 100.224 ms (39 rows)