2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 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

11.10. 操作符类和操作符族 #

索引定义可以为索引的每一列指定一个操作符类

CREATE INDEX name ON table (column opclass [ ( opclass_options ) ] [sort options] [, ...]);

操作符类标识索引在该列上使用的操作符。例如,类型为 int4 的 B-tree 索引将使用 int4_ops 类;此操作符类包含类型为 int4 的值的比较函数。实际上,列数据类型的默认操作符类通常就足够了。操作符类的主要目的是,对于某些数据类型,可能存在多种有意义的索引行为。例如,我们可能想按绝对值或实部对复数数据类型进行排序。我们可以通过为数据类型定义两个操作符类,然后在创建索引时选择正确的类来实现。操作符类决定了基本的排序顺序(随后可以通过添加排序选项 COLLATEASC/DESC 和/或 NULLS FIRST/NULLS LAST 来修改)。

除了默认操作符类之外,还有一些内置的操作符类。

  • 操作符类 text_pattern_opsvarchar_pattern_opsbpchar_pattern_ops 分别支持类型为 textvarcharchar 的 B-tree 索引。与默认操作符类的区别在于,值是逐个字符进行比较,而不是根据特定于区域设置的排序规则进行比较。这使得这些操作符类适用于涉及模式匹配表达式(LIKE 或 POSIX 正则表达式)的查询,当数据库不使用标准的“C”区域设置时。例如,您可以像这样索引一个 varchar 列:

    CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
    

    请注意,如果您希望涉及普通 <<=>>= 比较的查询能够使用索引,您也应该创建一个带有默认操作符类的索引。此类查询不能使用 xxx_pattern_ops 操作符类。(但是,普通相等性比较可以使用这些操作符类。)可以在同一列上创建多个具有不同操作符类的索引。如果您确实使用了 C 区域设置,则不需要 xxx_pattern_ops 操作符类,因为在 C 区域设置中,默认操作符类也可用于模式匹配查询。

以下查询显示了所有已定义的操作符类:

SELECT am.amname AS index_method,
       opc.opcname AS opclass_name,
       opc.opcintype::regtype AS indexed_type,
       opc.opcdefault AS is_default
    FROM pg_am am, pg_opclass opc
    WHERE opc.opcmethod = am.oid
    ORDER BY index_method, opclass_name;

操作符类实际上只是一个称为操作符族的更大结构的一个子集。在几种数据类型具有相似行为的情况下,经常需要定义跨数据类型的操作符并允许这些操作符与索引一起工作。为此,每种类型的操作符类必须分组到同一个操作符族中。跨类型操作符是该族的一部分,但与族内的任何单个类无关。

这个扩展版本的前一个查询显示了每个操作符类所属的操作符族。

SELECT am.amname AS index_method,
       opc.opcname AS opclass_name,
       opf.opfname AS opfamily_name,
       opc.opcintype::regtype AS indexed_type,
       opc.opcdefault AS is_default
    FROM pg_am am, pg_opclass opc, pg_opfamily opf
    WHERE opc.opcmethod = am.oid AND
          opc.opcfamily = opf.oid
    ORDER BY index_method, opclass_name;

此查询显示了所有已定义的操作符族以及每个族中包含的所有操作符。

SELECT am.amname AS index_method,
       opf.opfname AS opfamily_name,
       amop.amopopr::regoperator AS opfamily_operator
    FROM pg_am am, pg_opfamily opf, pg_amop amop
    WHERE opf.opfmethod = am.oid AND
          amop.amopfamily = opf.oid
    ORDER BY index_method, opfamily_name, opfamily_operator;

提示

psql 提供了命令 \dAc\dAf\dAo,它们提供了这些查询的稍高级版本。

提交更正

如果您在文档中发现任何不正确之处、与您对特定功能的实际使用不符之处,或需要进一步澄清之处,请使用此表单来报告文档问题。