热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

postgresql数据库计算索引的开销

每种索引访问模式都必须提供一个用于规划器/优化器的开销计算函数.这个函数的过程OID在访问模式在pg_am里的记录的amcostestimate字段里给出.注意:在PostgreSQL7.0以前,使用的是另外一种注册与索引相关的开销计算函数的模式.amcostestimate

    每种索引访问模式都必须提供一个用于规划器/优化器的开销计算函数. 这个函数的过程 OID 在访问模式在 pg_am 里的 记录的 amcostestimate 字段里给出.

    注意: 在 PostgreSQL 7.0 以前, 使用的是另外一种注册与索引相关的开销计算函数的模式.


    amcostestimate 函数收到一列 WHERE 子句,这些子句被认为对索引是有用的. 这个函数本身必须返回计算出来的访问索引的开销和 WHERE 子句的选择性( 也就是说,在索引扫描过程中主表行中要被捡索出来的部分). 对于简单的情况, 几乎所有开销计算器的工作都可以通过调用优化器里标准的过程来完成, 需要一个 amcostestimate 函数的原因是允许索引访问模式提供一些索引类型相关的信息, 这样就有可能改进标准的计算(预计).


    每个 amcostestimate 函数都必须有下面的名字:

void
amcostestimate (Query *root,
RelOptInfo *rel,
IndexOptInfo *index,
List *indexQuals,
Cost *indexStartupCost,
Cost *indexTotalCost,
Selectivity *indexSelectivity,
double *indexCorrelation);
    前面四个参数是输入:

root
    被处理的查询.

rel
    索引所处的关系(表).

index
    索引本身.

indexQuals
    索引条件子句列表(隐含地 AND);一个 NIL 列表表明没有可用的条件.


    最后四个参数是通过引用传递的输出:


*indexStartupCost
    设置为索引启动处理的开销

*indexTotalCost
    设置为索引处理的总开销

*indexSelectivity
    设置为索引选择性

*indexCorrelation
    设置索引扫描顺序和下层表的顺序之间的相关性系数


    请注意开销计算函数必须用 C 写,而不是 SQL 或者任何可以用的过程语言. 因为他们必须访问规划器/优化器的内部数据结构.


    索引访问开销应该以src/backend/optimizer/path/costsize.c 里面使用的单位计算: 一次顺序磁盘存储块抓取开销为 1.0, 一次非顺序抓取的开销为 random_page_cost, 并且处理一个索引记录的开销通常应该当做 cpu_index_tuple_cost (它是一个可以由用户调节的优化器参数).另外,应该用一个 cpu_operator_cost 的合适的倍数作为索引处理期间任何激活的比较操作符 (尤其是计算 indexQuals (索引查询)自己).

    访问开销应该包含所有与扫描索引本身的相关的磁盘和 CPU 开销, 而不是检索或处理被索引标识的主表索引的开销.

    "启动开销"是全部索引开销中在我们开始抓取第一条记录之前必须消耗的开销. 对于大多数索引,这部分可以当做零, 但是一个有着比较高启动开销的索引类型可能希望把这个值设置为非零.

    indexSelectivity (索引选择性)应该设置为在索引扫描过程中主表记录里将被检索出的部分. 如果是一个松索引的场合, 这个数字将明显地比实际传递给给出的资格条件的记录部分高.

    indexCorrelation 应该设置为索引顺序和表顺序的相关性系数(范围在 -1.0 和 1.0 之间).它用于调整从主表中抓取行的开销的计算.

    开销计算

    一次典型的开销计算器将象下面这样进行:

    计算和返回基于给出的资格条件的将要访问的主表的行数量. 如果不知到任何索引类型相关的信息,则使用标准的优化器函数 clauselist_selectivity():

*indexSelectivity = clauselist_selectivity(root, indexQuals,
lfirsti(rel->relids));
    

    计算(估计)在扫描过程中将要被访问的索引记录数. 对于许多索引类型,这个数字等于 indexSelectivity 乘以索引里面的记录数量, 但是它可以更多. (请注意索引在页面里的大小和记录可以从结构 IndexOptInfo 里获得.)

    计算(估计)在扫描过程中将要被检索出的索引页面数. 这个数字可以只是 indexSelectivity 乘以以页面数计算的索引的大小.

    计算索引访问开销.一个常见的计算器可以这样做:

    /*
     * (我们一般性的假设是索引页面将被顺序读入,
     *  因此它们每个的开销为1.0,没有 random_page_cose.
     *  同样,我们计算每条索引记录的索引条件的开销.
     *  所有开销都假设是在扫描过程中逐步递增的.)
     *
     * Our generic assumption is that the index pages will be read
     * sequentially, so they have cost 1.0 each, not random_page_cost.
     * Also, we charge for evaluation of the indexquals at each index tuple.
     * All the costs are assumed to be paid incrementally during the scan.
     */
    cost_qual_eval(&index_qual_cost, indexQuals);
    *indexStartupCost = 0;
    *indexTotalCost = numIndexPages +
        (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
    

    计算索引相关性.对于在一个字段上的简单排序的索引,这个它可以从 pg_statistic 中检索出来.如果相关性未知,保守的估计是零(不相关).

    开销计算器的例子可以在 src/backend/utils/adt/selfuncs.c 找到.

    通常,一个 amcostestimate 函数的 pg_proc 记录会应该显示八个参数,所有参数都声明为 internal (因为它们 的类型都不是 SQL 知道的类型),并且它们的返回类型是 void。


推荐阅读
  • 如何在Notepad++中执行Python代码
    Notepad++是一款功能丰富的文本编辑器,不仅支持多种编程语言的语法高亮显示,还提供了便捷的代码执行功能。本文将详细介绍如何在Notepad++中配置并运行Python代码。 ... [详细]
  • 在安装 SQL Server 时,选择混合验证模式可以提供更高的灵活性和管理便利性。如果您已经安装了 SQL Server 并使用单一的 Windows 身份验证模式,可以通过以下步骤将其更改为混合验证模式。 ... [详细]
  • 基于花生壳域名的Android与ESP8266远程控制系统搭建
    本文介绍了一种使用Android设备、ESP8266模块及路由器,结合花生壳动态域名解析服务实现远程控制的方法。通过该方法,用户能够有效解决因公网IP变动导致的连接问题,实现稳定可靠的远程控制。 ... [详细]
  • 本文继续探讨 Redis 分布式锁的高级特性,重点分析超时问题和可重入性的实现,以及如何通过不同的策略处理锁冲突。 ... [详细]
  • OpenWrt 是一款高度可定制的嵌入式 Linux 发行版,广泛应用于无线路由器等领域,拥有超过百个预装软件包。本文详细探讨如何在 OpenWrt 上通过 Luci 构建自定义模块,以扩展其功能。 ... [详细]
  • 导读上一篇讲了zsh的常用字符串操作,这篇开始讲更为琐碎的转义字符和格式化输出相关内容。包括转义字符、引号、print、printf的使用等等。其中很多内容没有必要记忆,作为手册参 ... [详细]
  • 本文探讨了Go语言(Golang)的学习价值及其在Web开发领域的应用潜力,包括其独特的语言特性和为什么它是现代软件开发的理想选择。 ... [详细]
  • Lua基本语法lua与C#的交互(相当简单详细的例子)
    lua脚本与C#的交互本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验——高分辨率用户请根据需求调整网页缩放比例)1LuaAndC#——L ... [详细]
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • 探索OpenWrt中的LuCI框架
    本文深入探讨了OpenWrt系统中轻量级HTTP服务器uhttpd的工作原理及其配置,重点介绍了LuCI界面的实现机制。 ... [详细]
  • Lua字符串1.字符串常见形式字符串或串(String)是由数字、字母、下划线组成的一串字符。Lua语言中字符串可以使用以下三种方式来表示:•单引号间的一串字符。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • 每种编程语言都有其独特的完成任务的方式,这也说明了为什么有这么多语言可供选择。在JimHall的《不同的编程语言如何完成相同的事情》文章中,他演示了13种不同的语言如何使用不同的语 ... [详细]
author-avatar
廖劫讲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有