假设我们有一个类似于这样的表
CREATE TABLE test1 ( id integer, content varchar );
并且应用程序发出许多如下形式的查询
SELECT content FROM test1 WHERE id = constant
;
在没有预先准备的情况下,系统将不得不逐行扫描整个 test1
表,以找到所有匹配的条目。如果 test1
中有很多行,而这样的查询只返回少数几行(可能为零或一行),这显然是一种低效的方法。但是,如果系统被指示在 id
列上维护索引,它可以使用更有效的方法来定位匹配的行。例如,它可能只需要深入搜索树的几个级别。
类似的方法也用于大多数非虚构书籍:读者经常查找的术语和概念被收集在书末的字母索引中。感兴趣的读者可以相对快速地扫描索引并翻到相应的页码,而不必阅读整本书来查找感兴趣的材料。正如作者的任务是预测读者可能查找的项目一样,数据库程序员的任务是预见哪些索引将是有用的。
可以使用以下命令在 id
列上创建索引,如上所述
CREATE INDEX test1_id_index ON test1 (id);
名称 test1_id_index
可以自由选择,但您应该选择一些能够让您以后记住索引用途的名称。
要删除索引,请使用 DROP INDEX
命令。可以随时向表中添加和删除索引。
创建索引后,无需进一步干预:当表被修改时,系统将更新索引,并且当它认为这样做比顺序表扫描更有效时,它将在查询中使用索引。但是,您可能需要定期运行 ANALYZE
命令来更新统计信息,以便查询规划器做出明智的决策。有关如何查找是否使用了索引以及规划器何时以及为何可能选择不使用索引的信息,请参阅第 14 章。
索引还可以使带有搜索条件的 UPDATE
和 DELETE
命令受益。索引还可以用于连接搜索。因此,在作为连接条件一部分的列上定义的索引也可以显着加快带有连接的查询。
一般来说,PostgreSQL 索引可以用于优化包含一个或多个如下形式的 WHERE
或 JOIN
子句的查询
indexed-column
indexable-operator
comparison-value
此处,indexed-column
是索引已定义在其上的任何列或表达式。indexable-operator
是索引列的索引运算符类的成员的运算符。(有关详细信息,请参见下文。)comparison-value
可以是任何非易失性且不引用索引表的表达式。
在某些情况下,查询规划器可以从另一个 SQL 构造中提取这种形式的可索引子句。一个简单的例子是,如果原始子句是
comparison-value
operator
indexed-column
如果原始operator
有一个属于索引运算符类成员的交换运算符,那么它可以翻转为可索引的形式。
在大表上创建索引可能需要很长时间。默认情况下,PostgreSQL 允许在创建索引的同时对表进行读取(SELECT
语句),但写入(INSERT
,UPDATE
,DELETE
)将被阻塞,直到索引构建完成。在生产环境中,这通常是不可接受的。可以允许在创建索引的同时进行写入,但需要注意一些注意事项 - 有关更多信息,请参见并发构建索引。
创建索引后,系统必须使其与表保持同步。这会增加数据操作的开销。索引也可能阻止创建仅堆元组。因此,应删除很少或从未使用过的索引。
如果您在文档中发现任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。