首页 文章

了解postgres解释w /位图堆/索引扫描

提问于
浏览
35

我有一张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告诉我的费用是多少?

对于记录,有773行, p_id 值为123456. mytable 上有38列 .

谢谢!

2 回答

  • 54

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

    事实并非如此 . EXPLAIN输出显示执行节点的结构,其中“更高”级别(不缩进)从它们下面的节点中拉出行 . 因此,当位图堆扫描节点转到第一行时,位图索引扫描会运行以确定要使用的行集,并将第一行的信息传递给堆扫描 . 索引扫描传递索引以确定需要读取哪些行,堆扫描实际读取它们 . 这个想法是通过从头到尾而不是按索引顺序读取堆,它将减少随机访问 - 当加载该页面时,将读取给定页面中的所有匹配行,并且可以读取足够的页面以便使用更便宜的顺序访问,而不是在整个磁盘上来回搜索 .

    为什么要检查425行?

    它真的检查行.1669316_ t . 与运行EXPLAIN ANALYZE相比,这使得EXPLAIN的值相当有限,后者实际运行查询并显示估计值和实际数字 .

    为什么操作321的宽度?

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

    12.04..1632.35和0.00..11.93告诉我的费用是多少?

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

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

  • 13

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

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

    3)成本数字中的第一个数字是初始化计划程序步骤的“启动”成本,第二个成本是该步骤的总成本 .

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

    您可能也希望在PostgreSQL Wiki中浏览这些链接:

    PostgreSQL EXPLAIN
    Using Explain

相关问题