↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 7.3 已于 2007 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE INDEX

CREATE INDEX — 定义一个新索引

大纲

CREATE [ UNIQUE ] INDEX index_name ON table
    [ USING acc_method ] ( column [ ops_name ] [, ...] )
    [ WHERE predicate ]
CREATE [ UNIQUE ] INDEX index_name ON table
    [ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] )
    [ WHERE predicate ]
  

输入

UNIQUE

使系统在创建索引时(如果数据已存在)以及每次添加数据时检查表中 的重复值。试图插入或更新会导致重复项的数据将产生一个错误。

index_name

要创建的索引名称。此处不能包含模式名称;索引始终创建在其父表 所在的同一模式中。

table

要建立索引的表名(可以是模式限定名)。

acc_method

用于索引的访问方法的名称。默认访问方法是 BTREE。PostgreSQL 为索引提供了四种访问方法:

BTREE

Lehman-Yao 高并发 B-树的一个实现。

RTREE

使用 Guttman 的二次分裂算法实现标准 R-tree。

HASH

Litwin 线性散列的一个实现。

GIST

广义索引搜索树。

column

表中一个列的名称。

ops_name

一个关联的操作符类。详见下文。

func_name

一个返回可索引值的函数。

predicate

定义部分索引的约束表达式。

输出

CREATE INDEX

索引成功创建时返回的消息。

ERROR: Cannot create index: 'index_name' already exists.

无法创建索引时出现此错误。

描述

CREATE INDEX 在指定的 table 上构建一个索引 index_name。

提示

索引主要用于提升数据库性能。但使用不当会导致性能下降。

在上面所示的第一种语法中,索引的键字段以列名指定。如果索引 访问方法支持多列索引,则可以指定多个字段。

在上面所示的第二种语法中,索引定义在把用户指定的函数 func_name 应用于单个表的 一个或多个列所得到的结果上。这些函数索引可用于 基于操作符的快速数据访问,而这些操作符通常需要对基础数据做某种 变换才能应用。例如,在 upper(col) 上定义的函数索引可让 子句 WHERE upper(col) = 'JIM' 使用索引。

PostgreSQL 为索引提供了 B-tree、R-tree、 hash 和 GiST 访问方法。B-tree 访问方法是 Lehman-Yao 高并发 B-树的 一个实现。R-tree 访问方法使用 Guttman 的二次分裂算法实现标准 R-tree。hash 访问方法是 Litwin 线性散列的一个实现。我们提到这些 算法只是为了说明所有这些访问方法都是完全动态的,不需要周期性地 进行优化(例如静态 hash 访问方法就需要)。

当 WHERE 子句存在时,会创建一个 部分索引。部分索引只包含表中一部分行的索引项, 通常这一部分比表的其余部分更有价值。例如,如果一个表同时包含 已开票和未开票订单,而未开票订单只占整个表的一小部分,但这一部分又经常 被访问,就可以只对这部分创建索引来提升性能。另一种可能 的应用是将 WHERE 与 UNIQUE 结合使用,以便在表的一个子集上强制唯一性。

WHERE 子句中使用的表达式只能引用底层表的列(但 它可以使用所有列,而不仅仅是被索引的列)。当前, WHERE 中也禁止使用子查询和聚合表达式。

所有在索引定义中使用的函数和操作符都必须是不可变的, 也就是说,它们的结果只能依赖其输入参数,而绝不能受任何外部因素影响 (例如另一个表的内容或当前时间)。这种限制确保索引的行为 定义明确。要在索引中使用用户定义的函数,记得在创建该函数时 将其标记为不可变的。

使用 DROP INDEX 删除索引。

注解

每当一个被索引的属性出现在使用下列操作符之一的比较中时, PostgreSQL 的查询优化器就会考虑使用 B-tree 索引: <, <=, =, >=, >

每当一个被索引的属性出现在使用下列操作符之一的比较中时, PostgreSQL 的查询优化器就会考虑使用 R-tree 索引: <<, &<, &>, >>, @, ~=, &&

每当一个被索引的属性出现在使用 = 操作符的比较中时, PostgreSQL 的查询优化器就会考虑使用 hash 索引。

测试表明 PostgreSQL 的 hash 索引与 B-tree 索引相当或更慢,而且 hash 索引的索引大小和构建时间要差得多。在高并发情况下 hash 索引 的表现也很差。由于这些原因,不鼓励使用 hash 索引。

目前,只有 B-tree 和 gist 访问方法支持多列索引。默认最多可指定 32 个键(构建 PostgreSQL 时可以更改 此限制)。目前只有 B-tree 支持唯一索引。

索引的每一列都可以指定一个操作符类。操作符类 标识索引用于该列的操作符。例如,四字节整数上的 B-tree 索引会使用 int4_ops 类;此操作符类包含四字节整数的比较函数。 实际上,字段数据类型的默认操作符类通常已足够。操作符类存在的主要原因是, 某些数据类型可能有多种有意义的排序方式。例如,我们可能希望按绝对值 或实部对复数数据类型排序。我们可以为该数据类型定义两个操作符类, 然后在创建索引时选择合适的类。还有一些具有特殊用途的操作符类:

  • 操作符类 box_ops 和 bigbox_ops 都支持在 box 数据类型上建立 R-tree 索引。 它们之间的区别是 bigbox_ops 会将 box 坐标缩小, 以避免对非常大的浮点坐标做乘法、加法和减法时出现浮点异常。 (注意:这在以前是成立的,但目前这两个操作符类都使用浮点, 实际上是等同的。)

下面的查询列出所有已定义的操作符类:

SELECT am.amname AS acc_method,
       opc.opcname AS ops_name
    FROM pg_am am, pg_opclass opc
    WHERE opc.opcamid = am.oid
    ORDER BY acc_method, ops_name;
    

用法

要在表 films 的字段 title 上 创建一个 B-tree 索引:

CREATE UNIQUE INDEX title_idx
    ON films (title);
  

兼容性

SQL92

CREATE INDEX 是 PostgreSQL 的语言扩展。

SQL92 中没有 CREATE INDEX 命令。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。