1

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

例如:

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

会还给我:

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

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

Index Scan using my_index_name on public.my_table (cost=...)<- 索引,好

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

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

在 PostgreSQL 文档中更深入地挖掘它说,当使用所述索引没有显着提高性能时,它仍然会使用顺序扫描。

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

我知道使用索引是相当基本的,那么这在生产环境中是绝对必要的吗?换句话说,PostgreSQL 会在需要使用索引时使用它,而不需要分析或清理作为额外任务吗?

4

1 回答 1

0

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

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

PostgreSQL 获取一个查询,解析它,然后开始计划过程。我们将如何扫描表?我们将如何加入他们以及以什么顺序?这些不是微不足道的决定,试图找到通常最好的做事方式通常意味着 PostgreSQL 需要了解有关表的一些信息。

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

所以 PostgreSQL 决定是否使用索引的方式是检查统计信息。现在,这些已经过时了,这就是您希望 autovacuum 更新它们的原因。你说你的表有几百条记录,而静态数据可能已经过时了。如果 PostgreSQL 不能说索引是一个胜利,它就不会使用它。数百条记录将接近“索引可能有帮助”的领域,具体取决于索引在清除记录时的选择性。

在您的大表中,根据现有统计数据,索引可能没有任何帮助。在您较小的表格中,可能有一个问题,它会根据其拥有的统计数据以一种方式得到回答,而根据新的统计数据以不同的方式回答。

于 2013-11-16T11:49:48.530 回答