【问题标题】:Understanding postgres explain w/ bitmap heap/index scans了解 postgres 解释 w/ 位图堆/索引扫描
【发布时间】:2012-04-26 01:34:57
【问题描述】:

我有一个包含 450 万行的表格。没有主键。该表有一个列p_id,类型为整数。使用btree 方法在此列上有一个索引idx_mytable_p_id。我愿意:

SELECT * FROM mytable WHERE p_id = 123456;

我对此进行了解释并看到以下输出:

Bitmap Heap Scan on mytable  (cost=12.04..1632.35 rows=425 width=321)
  Recheck Cond: (p_id = 543094)
  ->  Bitmap Index Scan on idx_mytable_p_id  (cost=0.00..11.93 rows=425 width=0)
        Index Cond: (p_id = 543094)

问题:

  • 为什么该查询先进行堆扫描,然后进行位图索引扫描?
  • 为什么要检查 425 行?为什么操作的宽度是321?
  • 告诉我 12.04..1632.35 和 0.00..11.93 的成本是多少?

据记录,p_id 值为 123456 的行有 773 行。mytable 上有 38 列。

谢谢!

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    为什么该查询先进行堆扫描,然后进行位图索引扫描?

    确实不是。 EXPLAIN 输出显示了执行节点的结构,“更高”级别的节点(没有缩进很远)从它们下面的节点中提取行。因此,当 Bitmap Heap Scan 节点开始提取其第一行时,Bitmap Index Scan 运行以确定要使用的行集,并将第一行的信息传递给堆扫描。索引扫描通过索引来确定需要读取哪些行,而堆扫描实际读取它们。这个想法是,通过从头到尾而不是按索引顺序读取堆,它将减少随机访问——加载该页面时将读取来自给定页面的所有匹配行,并且可以读取足够多的页面以便使用更便宜的顺序访问,而不是在整个磁盘上来回查找。

    为什么要检查 425 行?

    不是。你运行了 EXPLAIN,它只显示你的估计和选择的计划,它根本没有真正检查行。这使得 EXPLAIN 的值与运行 EXPLAIN ANALYZE 相比相当有限,EXPLAIN ANALYZE 实际上运行查询并向您显示估计值和实际数字。

    为什么操作的宽度是321?

    显然这是mytable 中元组的大小(以字节为单位)。

    告诉我12.04..1632.35和0.00..11.93的成本是多少?

    第一个数字是从该节点返回第一行的成本;第二个数字是返回该节点的所有行的成本。请记住,这些是估计值。单位是抽象成本单位。绝对数字没有任何意义;计划中重要的是哪个计划成本最低。如果您使用光标,则第一个数字很重要;否则通常是第二个数字。 (我认为它插入了一个 LIMIT 子句。)

    通常需要调整可配置的成本因素,例如 random_page_costcpu_tuple_cost,以便准确地为您的环境中的成本建模。如果没有这样的调整,比较成本可能与相应的运行时间不匹配,因此可能会选择不太理想的计划。

    【讨论】:

    • 内层操作的总成本会一直包含在外层操作的启动成本中。
    • @vyegorov 是对的,但需要注意的是,对于来自 EXPLAIN ANALYZE 的 实际 数据,您应该了解节点所用的总时间除以 loops 显示每次迭代的时间。如您所料,它是包含在封闭节点中的节点的总时间。
    【解决方案2】:

    re 1) 执行计划必须从最内层节点读取到最外层节点。所以它首先进行索引扫描(查找行)并访问实际表以返回索引扫描找到的行

    re 2) 计划中显示的行数只是基于统计数据的估计,因此 425 与 773 听起来相当合理。如果您想查看真实数字,请使用explain analyze

    re 3) 成本图中的第一个数字是初始化计划者步骤的“启动”成本,第二个成本是该步骤的总成本。

    这一切都记录在手册中: http://www.postgresql.org/docs/current/static/using-explain.html

    您可能还想浏览 PostgreSQL Wiki 中的这些链接:

    PostgreSQL EXPLAIN
    Using Explain

    【讨论】:

      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      相关资源
      最近更新 更多