更新时间:2026-07-28 GMT+08:00
分享

操作指导

前置条件

  • 数据库运行正常。
  • 反馈基数功能开启。
  • 数据库查询解析正常进入计划优化阶段。

使用指导

打开参数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秒,则会列入黑名单。

示例

受环境、版本及部署形态差异影响,示例中的执行计划可能与实际不同。本示例仅作为参考,具体优化效果请以实际执行计划为准。

  • 通过后台线程自动进行模型训练,调整执行计划。
  1. 启动数据库,查看enable_adaptive_cost参数是否开启,确保反馈基数估计功能的后台训练已正常开启。

    gaussdb=# SHOW enable_adaptive_cost;
     enable_adaptive_cost
    ----------------------
     on
    (1 row)

  2. 设置计划展示格式。

    gaussdb=# SET explain_perf_mode = pretty;

  3. 执行由于错误的基数估计导致次优计划的语句,如含有多种连接路径和连接类型的查询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;

  4. 观察执行计划可知,总执行时间为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)

  5. 再次执行查询并观察执行计划,可见执行时间已优化(从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选项展示模型使用情况,沿用上一节的执行计划。
  1. 设置计划展示格式,展示模型使用情况仅支持normal模式。

    gaussdb=# SET explain_perf_mode = normal;

  2. 在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;

  3. 观察执行计划输出,可见在算子详情中新增了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)

相关文档