zoukankan      html  css  js  c++  java
  • PostgreSQL在何处处理 sql查询之二十三

    再次回到  estimate_rel_size 我发现,
    在入口参数 rel中, rel->rd_rel->reltuples 的值已经完全准备好了:

    /*
     * estimate_rel_size - estimate # pages and # tuples in a table or index
     *
     * We also estimate the fraction of the pages that are marked all-visible in
     * the visibility map, for use in estimation of index-only scans.
     *
     * If attr_widths isn't NULL, it points to the zero-index entry of the
     * relation's attr_widths[] cache; we fill this in if we have need to compute
     * the attribute widths for estimation purposes.
     */
    void
    estimate_rel_size(Relation rel, int32 *attr_widths,
                      BlockNumber *pages, double *tuples, double *allvisfrac)
    {
        BlockNumber curpages;
        BlockNumber relpages;
        double        reltuples;
        BlockNumber relallvisible;
        double        density;
    
        switch (rel->rd_rel->relkind)
        {
            case RELKIND_RELATION:
            case RELKIND_INDEX:
            case RELKIND_TOASTVALUE:
    
                fprintf(stderr,"In %s...(double) rel->rd_rel->reltuples is: 
    %lf by process %d\n\n
    ",__FUNCTION__,

    (double) rel->rd_rel->reltuples, getpid()); /* it has storage, ok to call the smgr */ curpages = RelationGetNumberOfBlocks(rel); //fprintf(stderr,"In %s...(double) rel->rd_rel->reltuples is:
                     %lf by process %d\n\n",__FUNCTION__,
                          (double) rel->rd_rel->reltuples, getpid());
    /* * HACK: if the relation has never yet been vacuumed, use a * minimum size estimate of 10 pages. The idea here is to avoid * assuming a newly-created table is really small, even if it * currently is, because that may not be true once some data gets * loaded into it. Once a vacuum or analyze cycle has been done * on it, it's more reasonable to believe the size is somewhat * stable. * * (Note that this is only an issue if the plan gets cached and * used again after the table has been filled. What we're trying * to avoid is using a nestloop-type plan on a table that has * grown substantially since the plan was made. Normally, * autovacuum/autoanalyze will occur once enough inserts have * happened and cause cached-plan invalidation; but that doesn't * happen instantaneously, and it won't happen at all for cases * such as temporary tables.) * * We approximate "never vacuumed" by "has relpages = 0", which * means this will also fire on genuinely empty relations. Not * great, but fortunately that's a seldom-seen case in the real * world, and it shouldn't degrade the quality of the plan too * much anyway to err in this direction. * * There are two exceptions wherein we don't apply this heuristic. * One is if the table has inheritance children. Totally empty * parent tables are quite common, so we should be willing to * believe that they are empty. Also, we don't apply the 10-page * minimum to indexes. */ if (curpages < 10 && rel->rd_rel->relpages == 0 && !rel->rd_rel->relhassubclass && rel->rd_rel->relkind != RELKIND_INDEX) curpages = 10; /* report estimated # pages */ *pages = curpages; /* quick exit if rel is clearly empty */ if (curpages == 0) { *tuples = 0; *allvisfrac = 0; break; } /* coerce values in pg_class to more desirable types */ relpages = (BlockNumber) rel->rd_rel->relpages; reltuples = (double) rel->rd_rel->reltuples; //fprintf(stderr,"In %s...reltuples is: %lf\n by process %d",
    __FUNCTION__,reltuples, getpid());
    relallvisible = (BlockNumber) rel->rd_rel->relallvisible; /* * If it's an index, discount the metapage while estimating the * number of tuples. This is a kluge because it assumes more than * it ought to about index structure. Currently it's OK for * btree, hash, and GIN indexes but suspect for GiST indexes. */ if (rel->rd_rel->relkind == RELKIND_INDEX && relpages > 0) { curpages--; relpages--; } /* estimate number of tuples from previous tuple density */ if (relpages > 0) density = reltuples / (double) relpages; else { /* * When we have no data because the relation was truncated, * estimate tuple width from attribute datatypes. We assume * here that the pages are completely full, which is OK for * tables (since they've presumably not been VACUUMed yet) but * is probably an overestimate for indexes. Fortunately * get_relation_info() can clamp the overestimate to the * parent table's size. * * Note: this code intentionally disregards alignment * considerations, because (a) that would be gilding the lily * considering how crude the estimate is, and (b) it creates * platform dependencies in the default plans which are kind * of a headache for regression testing. */ int32 tuple_width; tuple_width = get_rel_data_width(rel, attr_widths); tuple_width += sizeof(HeapTupleHeaderData); tuple_width += sizeof(ItemPointerData); /* note: integer division is intentional here */ density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width; } *tuples = rint(density * (double) curpages); //fprintf(stderr,"In %s...*tuples is: %lf\n by process %d",
                  __FUNCTION__,*tuples, getpid());
    /* * We use relallvisible as-is, rather than scaling it up like we * do for the pages and tuples counts, on the theory that any * pages added since the last VACUUM are most likely not marked * all-visible. But costsize.c wants it converted to a fraction. */ if (relallvisible == 0 || curpages <= 0) *allvisfrac = 0; else if ((double) relallvisible >= curpages) *allvisfrac = 1; else *allvisfrac = (double) relallvisible / curpages; break; case RELKIND_SEQUENCE: /* Sequences always have a known size */ *pages = 1; *tuples = 1; *allvisfrac = 0; break; case RELKIND_FOREIGN_TABLE: /* Just use whatever's in pg_class */ *pages = rel->rd_rel->relpages; *tuples = rel->rd_rel->reltuples; *allvisfrac = 0; break; default: /* else it has no disk storage; probably shouldn't get here? */ *pages = 0; *tuples = 0; *allvisfrac = 0; break; } }

    然后,需要回溯到上一个层面,查找源头。

  • 相关阅读:
    Thread.Join
    WPF几个基础概念的浅显理解
    Vue v-bind指令
    Vue设置路由跳转的两种方法: <router-link :to="..."> 和router.push(...)
    前端上传视频、图片、文件等大文件 组件Plupload使用指南
    vue如何获取并操作DOM元素
    css中border-sizing属性详解和应用
    vue使用axios发送post请求时的坑及解决原理
    vue中的js引入图片,使用require相关问题
    vue 动态添加body背景图片
  • 原文地址:https://www.cnblogs.com/gaojian/p/3103594.html
Copyright © 2011-2022 走看看