索引列不仅限于底层表的列,还可以是从表的一个或多个列计算得出的函数或标量表达式。此功能有助于基于计算结果快速访问表。

例如,一种常见的进行大小写不敏感比较的方法是使用 lower 函数:

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

如果已经在 lower(col1) 函数的结果上定义了索引,那么这条查询就可以使用该索引:

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

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

再举一个例子,如果经常执行如下查询:

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

那么创建如下索引可能是值得的:

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

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

维护索引表达式相对昂贵,因为每次插入行和非 HOT 更新时都需要计算这些派生表达式。然而,在索引搜索期间不会重新计算索引表达式,因为它们已经存储在索引中。在上面的两个例子中,系统将查询视为 WHERE indexedcolumn = 'constant',因此搜索的速度与任何其他简单的索引查询相同。

因此,当检索速度比插入和更新速度更重要时,基于表达式的索引非常有用

相关链接

PostgreSQL: Documentation: 16: 11.7. Indexes on Expressions

OB tags

#PostgreSQL