索引未使用Postgres

时间:2012-08-31 18:56:45

标签: sql database postgresql

跟踪索引并分析索引添加的表,我们遇到一些情况: 我们的一些表有索引,但是当我在索引字段上执行带有子句where的查询时,不会在您的idx_scan字段中分别考虑。同样的relname和schemaname,所以,我不能错。

测试更多,我删除并再次创建表,之后查询返回到帐户idx_scan

对于另一个表也发生了这种情况,我们使用索引执行了一些查询,并且没有考虑idx_scan字段,仅在seq_scan中,即使我在同一个表中使用索引创建另一个字段,这个新字段也不计算idx_scan。

这些表的问题是什么?我们做错了什么?只有当我创建一个包含idx_scan帐户索引的新表时,才会出现错误的旧表。 我们有时会使用这个数据库进行迁移,也许这可能是问题所在?发生在localhost和服务器上。

我们看到的另一个事件,一些索引被计算,idx_scan> 0,当执行查询选择时,不再增加idx_scan,数字是固定的,只是增加seq_scan。 我相信这些问题可能是相关的。

我很感激一些帮助,这是一个很大的谜,我们的数据库徘徊,并且不知道问题是什么。

1 个答案:

答案 0 :(得分:0)

一些建议(以及添加到您问题中的内容)。

首先,索引扫描并不总是受到顺序扫描的青睐。例如,如果您的表很小或规划器估计需要提取大多数页面,则将省略索引扫描以支持顺序扫描。

请记住:没有任何计划能够从磁盘上检索单个页面并顺序运行它。

类似地,如果你必须检索50%的关系页面,那么进行索引扫描会使磁盘/ IO总量略微减少,从而获得更多随机磁盘/ IO。如果你使用SSD,它可能是一个胜利,但肯定不是传统的硬盘驱动器。毕竟你真的不想等待拼盘转向。如果您使用的是SSD,则可以相应地调整计划器设置。

所以索引与顺序扫描不是故事的结尾。问题是检索了多少行,表有多大,检索磁盘页面的百分比等等。

如果它真的是选择了一个糟糕的计划(而不是你没有考虑的好计划!)那么问题就变成了原因。有一些设置统计目标的方法,但这些方法可能不太有用。

最后,计划程序在某些您可能喜欢的情况下实际上无法选择索引。例如,假设我有一个1000万行表,其记录跨越5年(平均每年约200万行)。我想得到截然不同的岁月。我无法使用标准查询和索引来执行此操作,但我可以构建一个WITH RECURSIVE CTE,以便基本上每年执行一次相同的查询,并使用索引。当然,在这种情况下你最好有一个索引,或者WITH RECURSIVE会每年进行一次顺序扫描,这肯定不是你想要的!

tl;博士:这很复杂。你想在得出结论之前确定这是一个糟糕的计划,然后如果这是一个糟糕的计划,请根据你的配置看看你可以做些什么。