0

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

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

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

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

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

我很感激一些帮助,这是我们数据库的一个大谜团,不知道问题可能是什么。

4

1 回答 1

0

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

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

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

类似地,如果你必须检索一个关系的 50% 的页面,那么进行索引扫描将会用更少的磁盘/IO 总量来换取更多的随机磁盘/IO。如果您使用 SSD,但肯定不是使用传统硬盘驱动器,这可能是一个胜利。毕竟你真的不想等待盘片转动。如果您使用的是 SSD,您可以相应地调整规划器设置。

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

如果它真的选择了一个糟糕的计划(而不是一个你没有考虑过的好计划!)那么问题就变成了为什么。有一些方法可以设置统计目标,但这些方法可能并没有真正的帮助。

最后,在您可能喜欢的某些情况下,计划者确实无法选择索引。例如,假设我有一个包含 5 年记录的 1000 万行表(平均每年大约 200 万行)。我想得到不同的年份。我不能用标准查询和索引来做到这一点,但我可以构建一个 WITH RECURSIVE CTE 来基本上每年执行一次相同的查询,并且将使用索引。当然,在这种情况下你最好有一个索引,否则 WITH RECURSIVE 将每年进行一次顺序扫描,这肯定不是你想要的!

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

于 2012-09-01T01:44:37.493 回答