天天看點

Greenplum資料庫統計資訊——analyze指令

前面分享PostgreSQL資料庫統計資訊——analyze指令部落格說明,這裡就看一下Greenplum資料庫統計資訊analyze指令與PostgreSQL的差異。從gram.y檔案中可以看出greenplum新增ROOTPARTITION/FULLSCAN選項(analyze verbose ROOTPARTITON relation_list;analyze verbose ROOTPARTITON ALL;analyze verbose FULLSCAN relation_list),其文法處理就是向VacuumStmt的options成員中添加makeDefElem(“rootpartition”, NULL, @3)或makeDefElem(“fullscan”, NULL, @3))。

Greenplum資料庫統計資訊——analyze指令

ROOTPARTITION [ALL]用于基于分區表子表上的資料收集根分區上的統計資訊。如果可能,ANALYZE使用葉子分區統計資訊生成根分區統計資訊。否則,ANALYZE通過對葉子分區資料進行采樣來收集統計資訊。ExecVacuum函數新增rootonly和fullscan兩個bool變量用于處理上述新增options,并設定相應的params.options為VACOPT_ROOTONLY或VACOPT_FULLSCAN。VACOPT_ROOTONLY影響到expand_vacuum_rel函數和get_all_vacuum_rels函數,用于擷取所有需要分析表清單時剔除子表或剔除父表(disable optimizer_analyze_root_partition)。

FULL SCAN就是利用SPI執行​

​select pg_catalog.gp_hyperloglog_accum(columnname) from schemaName.RelationName as Ta​

​以通過hyperloglog擴充的gp_hyperloglog_accum函數為整個表擷取HLL counter值,并将計數值存放到統計資訊的stahll_full字段中去。

| analyze_keyword opt_verbose ROOTPARTITION vacuum_relation_list
        {
          VacuumStmt *n = makeNode(VacuumStmt);
          n->options = NIL;
          if ($2)
            n->options = lappend(n->options,
                       makeDefElem("verbose", NULL, @2));
          n->options = lappend(n->options,
                     makeDefElem("rootpartition", NULL, @3));
          n->rels = $4;
          n->is_vacuumcmd = false;
          $$ = (Node *)n;
        }
      | analyze_keyword opt_verbose ROOTPARTITION ALL
        {
          VacuumStmt *n = makeNode(VacuumStmt);
          n->options = NIL;
          if ($2)
            n->options = lappend(n->options,
                       makeDefElem("verbose", NULL, @2));
          n->options = lappend(n->options,
                     makeDefElem("rootpartition", NULL, @3));
          n->rels = NIL;
          n->is_vacuumcmd = false;
          $$ = (Node *)n;
        }
      | analyze_keyword opt_verbose FULLSCAN vacuum_relation_list
        {
          VacuumStmt *n = makeNode(VacuumStmt);
          n->options = NIL;
          if ($2)
            n->options = lappend(n->options,
                       makeDefElem("verbose", NULL, @2));
          n->options = lappend(n->options,
                     makeDefElem("fullscan", NULL, @3));
          n->rels = $4;
          n->is_vacuumcmd = false;
          $$ = (Node *)n;
        }      

以下差異為greenplum分布式統計資訊收集,主要通過ctx來區分是QD還是QE在執行該段代碼。

Greenplum資料庫統計資訊——analyze指令

do_analyze_rel函數在postgresql中的主要流程如下。準備工作流程: 1. 建立anl_context記憶體上下文,并切換到該記憶體上下文中 2. 切換到表所有者的userid,以便任何索引函數都作為該使用者運作 3. 需要進一步确定要分析一個表中的哪些列:使用者可能指定隻分析表中的某幾個列,被頻繁通路的列才更有被分析的價值,然後還要打開待分析表的所有索引,看看是否有可以被分析的。列采樣工作流程: 1. 使用所有可分析列中的最壞情況,确定需要采樣的行數 2. 使用采樣函數擷取采樣行 3. 計算統計資料。而greenplum的do_analyze_rel函數由于需要處理params.options為VACOPT_FULLSCAN的情況和分布式采樣QE流程ctx不為null的流程,是以有相當的差異。

Greenplum資料庫統計資訊——analyze指令

greenplum這裡采用的acquire_sample_rows和acquire_inherited_sample_rows是分布式采樣函數,而不是普通的采樣函數。

統計資訊計算流程和統計資訊更新流程對hll統計資訊做了相應的處理,如下所示。

Greenplum資料庫統計資訊——analyze指令