索引列不一定非得是底层表中的某一列,也可以是一个由表中一列或多列计算得到的函数或标量表达式。这个特性有助于基于计算结果来快速访问表。
例如,进行大小写不敏感比较的一种常见方式,是使用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',因此搜索速度与其他简单索引查询相同。因此,当检索速度比插入和更新速度更重要时,表达式索引会很有用。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。