一、核心概念
表达式索引的索引列不是底层数据表的物理列,而是由表中一列或多列通过函数或标量表达式计算得到的衍生值。
该特性支持基于计算结果快速检索表中数据,适用于需要按自定义计算逻辑查询的业务场景。
二、典型应用示例
2.1 大小写不敏感查询优化
在字符串查询中,若需要忽略大小写匹配,通常使用 lower() 函数统一字符格式,示例如下:
-- 原始查询:基于lower函数计算结果过滤数据
SELECT * FROM test1 WHERE lower(col1) = 'value';
为提升此类查询的效率,可直接基于 lower(col1) 的计算结果创建表达式索引:
-- 创建普通表达式索引
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
-- 创建唯一表达式索引:阻止col1仅大小写不同的重复数据插入
CREATE UNIQUE INDEX test1_lower_col1_idx ON test1 (lower(col1));
2.2 多列拼接结果查询优化
当业务需要频繁基于多列拼接的结果进行查询时,可针对拼接表达式创建索引,示例如下:
-- 原始查询:基于姓名拼接结果过滤数据
SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';
-- 创建表达式索引:注意复合表达式需要加外层圆括号
CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
三、语法规则
| 表达式类型 | 语法要求 | 示例 |
|---|---|---|
| 单一函数调用 | 表达式外侧圆括号可省略 | lower(col1) |
| 复合运算/拼接 | 表达式外侧圆括号必须添加 | `(first_name |
四、性能特性
4.1 写入性能开销
表达式索引的维护成本高于普通索引:
- 数据插入时,需先计算表达式值,再将结果写入索引;
- 数据非HOT更新(Heap-Only Tuple)时,需重新计算表达式值并更新索引。
4.2 查询性能优势
索引搜索阶段无需重新计算表达式值,因为计算结果已提前存储在索引中。
数据库会将原查询优化为 WHERE indexedcolumn = 'constant' 的形式,查询效率与普通单列索引完全一致。
4.3 适用场景
优先用于 检索频率远高于插入/更新频率 的场景,例如:
- 报表统计与数据分析查询
- 高频访问的业务检索接口
- 数据归档后的历史数据查询
- 日期格式化查询场景:如频繁按“年-月”格式查询数据(基于DATE_FORMAT(date_col, '%Y-%m')表达式)
- 数值计算结果过滤场景:如电商平台按“商品单价×折扣”后的折后价检索商品(基于price×discount表达式)
- 字符串截取查询场景:如按手机号后4位检索用户(基于RIGHT(phone, 4)表达式)
五、关键总结
- 表达式索引基于列的计算结果构建,核心解决“按函数/表达式结果快速查询”的需求;
- 语法上需区分表达式类型,复合运算必须添加外层圆括号;
- 该索引以写入性能损耗换取查询效率提升,需根据业务读写比例合理选择;
- 唯一表达式索引可限制表达式结果重复,实现更精准的数据唯一性约束。