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

我有一张桌子,有四百五十万行。 没有主键。 该表有一个列p_id ,types为整数。 使用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告诉我的费用是多less?

logging中有773行, p_id值为p_id上有38列。

谢谢!

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

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

为什么检查425行?

不是。 你运行EXPLAIN,它只是显示你的估计和select的计划,它根本不检查行。 与运行EXPLAIN ANALYZE相比,EXPLAIN的价值非常有限,EXPLAIN ANALYZE实际上运行查询并显示估算值和实际值。

为什么操作321的宽度?

显然,这是mytable组的大小,以字节为单位。

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

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

通常需要调整可configuration的成本因素(如random_page_costcpu_tuple_cost ,以便在您的环境中准确build模成本。 如果没有这样的调整,相对成本可能不符合相应的运行时间,因此可能会select一个不太理想的计划。

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

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

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

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

您也可以在PostgreSQL Wiki中查看这些链接:

PostgreSQL的解释
使用说明