where 子句中的 function

1
2
3
SELECT first_name, last_name, phone_number
FROM employees
WHERE UPPER(last_name) = UPPER('winand')

虽然 LAST_NAME 已有索引,但是执行计划并没有使用索引,仍然是全表扫描。因为数据库认为函数的计算结果跟传入参数之间并不相关。为了支持该查询,需要新建一个涵盖实际搜索词的索引。

1
2
CREATE INDEX emp_up_name 
ON employees (UPPER(last_name))

这种在定义中包含函数或者运算表达式的索引称为基于函数的索引 (function-based index)。建索引时执行相关的计算并把计算结果存到索引中。

为了使数据库能正确地决定何时使用索引,在索引更新时,应该更新相应表的 statistics。

在 SQL Server 中通过 computed column 来实现类似的功能:

1
2
3
ALTER TABLE employees ADD last_name_up AS UPPER(last_name)

CREATE INDEX emp_up_name ON employees (last_name_up)

需要注意的是,在索引中使用的函数必须是确定性函数 (deterministic function)。只要使用特定的输入值集并且数据库具有相同的状态,那么不管何时调用,确定性函数始终都会返回相同的结果。

参考资料:

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/indexes-on-computed-columns?view=sql-server-ver15

作者

Jesse

发布于

2021-06-02

更新于

2021-07-19

许可协议

评论