PostgreSQL需要VACUUM或ANALYZE计划来使用索引吗?

时间:2013-09-19 07:40:26

标签: sql database postgresql indexing

我正在为现有的PostgreSQL数据库实例中的表创建索引。据我所知,EXPLAIN ANALYZE后跟应用程序的SQL命令是了解我的索引是否被使用的最简单方法。

例如:

EXPLAIN ANALYZE SELECT A,B,C FROM MY_TABLE WHERE C=123;

会让我回来:

Seq Scan on public.my_table (cost=...)< - 没有索引,BAD

并且,在创建索引之后,它将返回:

Index Scan using my_index_name on public.my_table (cost=...)< - Index,GOOD

在我的优化任务中,我找到了一个相对较大的表,偶尔出现性能问题,并为此创建了一个索引。这是将顺序扫描转换为索引扫描的完美示例,如上所述。它奏效了。

然而,在创建索引之后,第二个查询在列表中排名最慢,仍然不到0.5秒,索引没有任何区别!创建索引后,它仍然会执行Seq Scan。该表虽然有几百条记录,但每年可能增长几千条。

在PostgreSQL文档中深入挖掘一下,它说如果使用上述索引没有显着的性能提升,它仍会使用顺序扫描。

然后可怕的部分:有人建议您运行ANALYZE或启用“Autovacuum”守护程序。这样,数据库就可以知道表的大小并正确地确定查询计划。

我理解使用索引是相当基本的,所以这在生产环境中是绝对必要的吗?换句话说,将会在需要时使用索引时使用索引而无需分析或真空作为一项额外任务?

1 个答案:

答案 0 :(得分:0)

简短回答“只需运行autovacuum。”答案很长......是的,因为统计数据可能已经过时了。

让我们来谈谈索引以及PostgreSQL如何/何时决定使用它们。

PostgreSQL获取查询,解析它,然后开始计划过程。我们怎么去扫描桌子?我们如何加入他们以及以什么顺序加入他们?这些不是微不足道的决定,试图找到通常最好的方法来做事通常意味着PostgreSQL需要知道关于表的一些事情。

首先要注意的是索引并不总是胜利。没有计划能够通过单页表进行顺序扫描,即使是5页表,顺序扫描也几乎总是比索引扫描更快。所以PostgreSQL无法安全地决定“使用所有可用的索引。”

因此PostgreSQL决定是否使用索引的方式是检查统计信息。现在,这些已经过时了,这就是为什么你想让autovacuum更新它们。你说你的表有几百条记录,静态可能已经过时了。如果PostgreSQL不能说索引是胜利,它就不会使用它。几百条记录将接近“索引可能有所帮助”的区域,具体取决于索引在清除记录方面的选择性。

在您的大表中,基于现有统计数据可能没有问题,索引会有所帮助。在你的小桌子里,可能有一个问题,它根据它的统计数据以一种方式得到回答,并根据较新的统计数据采用不同的方式。