11.1. Introduction

假设我们有一个与此类似的表:

CREATE TABLE test1 (
    id integer,
    content varchar
);

然后应用程序发出以下形式的许多查询:

SELECT content FROM test1 WHERE id = constant;

如果没有提前准备,系统将不得不逐行扫描整个test1表,以找到所有匹配的条目。如果test1中有很多行,而这样的查询仅返回几行(也许为零或一),则显然这是一种低效的方法。但是,如果已指示系统在id列上维护索引,则可以使用更有效的方法来定位匹配的行。例如,它可能只需要深入搜索树中几级即可。

大多数非小说类图书中都使用了类似的方法:Reader 经常查找的术语和概念都收录在书末的字母索引中。有兴趣的 Reader 可以相对快速地扫描索引,然后翻到相应的页面,而不必阅读整本书来查找感兴趣的材料。正如预期 Reader 可能会查找的项目是作者的任务一样,数据库程序员的任务是预见哪些索引将是有用的。

如下所述,可以使用以下命令在id列上创建索引:

CREATE INDEX test1_id_index ON test1 (id);

名称test1_id_index可以自由选择,但是您应该选择一些名称,以便稍后记住该索引的用途。

要删除索引,请使用DROP INDEX命令。索引可以随时添加到表中或从表中删除。

创建索引后,无需进一步干预:系统将在修改表后更新索引,并且当它认为这样做比 Sequences 表扫描更有效时,它将在查询中使用索引。但是您可能必须定期运行ANALYZE命令来更新统计信息,以允许查询计划者做出有根据的决策。有关如何查找是否使用索引以及计划者何时以及为何选择不使用索引的信息,请参见Chapter 14

索引还可使具有搜索条件的UPDATEDELETE命令受益。此外,索引可用于联接搜索。因此,在作为联接条件一部分的列上定义的索引也可以显着加快使用联接的查询。

在大表上创建索引可能需要很长时间。默认情况下,PostgreSQL 允许在创建索引的同时在表上进行读取(SELECT语句),但是在索引构建完成之前,写入(INSERTUPDATEDELETE)被阻止。在生产环境中,这通常是不可接受的。可以允许在创建索引的同时进行写操作,但是需要注意一些注意事项-有关更多信息,请参见同时构建索引

创建索引后,系统必须使其与表保持同步。这增加了数据处理操作的开销。因此,应删除很少或从不在查询中使用的索引。