Skip to content

11.7. 表达式索引#

索引列不必只是基础表的列,还可以是根据表中一个或多个列计算出的函数或标量表达式。此功能可用于根据计算结果快速访问表。

例如,执行不区分大小写的比较的一种常见方法是使用lower函数

SELECT * FROM test1 WHERE lower(col1) = 'value';

如果已针对lower(col1)函数的结果定义索引,则此查询可以使用索引

CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));

如果我们声明此索引UNIQUE,它将阻止创建col1值仅在大小写上不同的行,以及col1值实际上完全相同。因此,表达式索引可用于强制无法定义为简单唯一约束的约束。

再举一个例子,如果经常执行类似于以下内容的查询

SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';

那么创建类似于以下内容的索引可能是值得的

CREATE INDEX people_names ON people ((first_name || ' ' || last_name));

CREATE INDEX命令的语法通常要求在索引表达式周围编写括号,如第二个示例所示。当表达式只是函数调用时,可以省略括号,如第一个示例所示。

索引表达式的维护成本相对较高,因为必须为每个行插入和非 HOT 更新计算派生表达式。但是,索引表达式在索引搜索期间不会重新计算,因为它们已存储在索引中。在以上两个示例中,系统将查询视为WHERE indexedcolumn = 'constant',因此搜索速度等同于任何其他简单索引查询。因此,当检索速度比插入和更新速度更重要时,表达式索引非常有用。