On this page
11.7. 表达式索引
索引列不必只是基础表的一列,而可以是从表的一个或多个列计算出的函数或标量表达式。此功能对于基于计算结果快速访问表很有用。
例如,进行不区分大小写的比较的常用方法是使用lower
函数:
SELECT * FROM test1 WHERE lower(col1) = 'value';
如果在lower(col1)
函数的结果上定义了一个索引,则此查询可以使用索引:
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
表达式索引还可以控制唯一索引的范围。例如,此唯一索引防止重复的整数值存储在double precision
类型的列中:
CREATE UNIQUE INDEX test1_uniq_int ON tests ((floor(double_col)))
如果我们将这个索引声明为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
命令的语法通常需要在索引表达式周围写括号,如第二个示例所示。如第一个示例所示,当表达式只是函数调用时,可以省略括号。
索引表达式的维护成本相对较高,因为必须在插入时以及每当更新行时为每一行计算派生表达式。但是,索引表达式在索引搜索过程中不会被重新计算,因为它们已经存储在索引中。在以上两个示例中,系统都将查询视为WHERE indexedcolumn = 'constant'
,因此搜索速度等同于任何其他简单索引查询。因此,当检索速度比插入和更新速度更重要时,表达式索引非常有用。