SQL函数考察重点是判断性能影响、避免隐式转换及设计高效逻辑;在WHERE中对索引列用函数(如UPPER(name))会导致索引失效,应改用等值查询或函数索引。

SQL函数在面试中常被用来考察候选人对数据库原理、执行计划和实际优化能力的理解。重点不在死记硬背语法,而在于能否判断函数何时拖慢查询、如何避免隐式转换、以及怎样设计既安全又高效的自定义逻辑。
函数导致索引失效的典型场景
很多性能问题源于对函数作用位置的误判。当在 WHERE 条件的列上直接使用函数(如 WHERE UPPER(name) = 'JOHN'),数据库通常无法走该列上的普通索引,因为索引是按原始值排序构建的,函数改变了匹配方式。
- ✅ 推荐写法:用
name = 'john'配合大小写敏感索引,或建函数索引(如 Oracle/PostgreSQL 支持CREATE INDEX idx_name_upper ON users (UPPER(name))) - ❌ 避免写法:对索引列做运算或函数调用,如
WHERE YEAR(create_time) = 2023;应改用范围查询create_time >= '2023-01-01' AND create_time - 注意 MySQL 8.0+ 支持函数索引,但需显式创建,且不是所有函数都允许(如不能含子查询或不确定函数)
标量函数 vs 表值函数的执行开销差异
标量函数(返回单个值)在 SELECT 或 WHERE 中每行调用一次,若逻辑复杂或涉及 I/O(如查表、调用外部服务),会显著放大执行时间;表值函数(返回结果集)则可能被优化器当作内联视图处理,有重写空间。
- SQL Server 中,多语句标量函数默认强制逐行执行,即使简单如
LEN()在旧版本也会阻断并行;建议优先用内联表达式替代 - PostgreSQL 的 SQL 函数若声明为
STABLE或IMMUTABLE,优化器可做更多推导(如提前计算、去重调用) - MySQL 自定义函数不支持执行计划提示,且无法在 GROUP BY 或 ORDER BY 中下推过滤,慎用于高频聚合场景
自定义函数设计的三个关键约束
面试官常通过函数设计题考察工程意识。一个“好”的数据库函数应满足确定性、低副作用、易维护三点。
-
确定性(Deterministic):相同输入永远输出相同结果。避免依赖
NOW()、RAND()、用户变量等非稳定因子;否则不仅影响缓存,还可能导致主从不一致 - 无副作用(No Side Effects):函数内部不应修改数据(INSERT/UPDATE/DELETE)、发消息、写日志。数据库函数本质是“读”操作,写行为应交给存储过程或应用层
-
参数防御与类型明确:显式声明参数类型(如
DECIMAL(10,2)而非FLOAT),对 NULL 输入定义清晰行为(返回 NULL?抛异常?默认值?),避免隐式转换引发意料外结果
常见函数陷阱与替代方案
一些看似无害的函数组合,在大数据量下会成为瓶颈。
-
LIKE '%abc'无法利用索引,考虑全文索引(tsvector/FULLTEXT)或倒排结构 -
COALESCE(col, 'default')在 WHERE 中使用时,可能掩盖真实 NULL 分布,影响统计信息准确性;必要时拆成col IS NULL OR col = 'default' -
JSON_EXTRACT(json_col, '$.name')在 MySQL 中无法走索引,5.7+ 可建虚拟列 + 索引:ALTER TABLE t ADD name_virt VARCHAR(50) AS (JSON_UNQUOTE(JSON_EXTRACT(json_col, '$.name')))


















