注意:数据库函数本身不是万能,很多场景下函数会造成索引失效;只有合理使用,才能提升查询效率,下面区分「适合用函数提速」和「避坑点」。
一、适合用数据库函数优化查询的场景
1. 聚合统计场景(聚合函数)
业务需要统计汇总,避免把大量原始数据拉到应用层做计算,把计算下压到数据库引擎,减少网络 IO、减少应用内存开销。
COUNT / SUM / AVG / MAX / MIN / GROUP_CONCAT场景:报表统计、指标汇总、分组统计
-- 数据库侧直接算出结果,不用把千万行数据返回Java程序再求和
SELECT user_id,SUM(order_amount) FROM t_order GROUP BY user_id;
✅收益:减少返回行数,网络传输量大幅下降。
2. 字段简单转换、清洗(查询投影 SELECT 列)
只对输出字段做函数处理,WHERE 条件不套函数,索引不受影响。
关键点:函数写在
SELECT后,不要写在 WHERE 条件的索引列上。
日期格式化、字符串截取、脱敏、数值换算
-- select投影使用函数,where条件保持原始字段,索引正常生效
SELECT DATE_FORMAT(create_time,'%Y-%m-%d'),SUBSTR(phone,1,3) FROM t_user WHERE create_time >= '2026‑01‑01';
✅收益:数据库完成格式化,应用层省去循环处理,减少代码。
3. 分区裁剪相关函数(分区表)
时间分区表中,分区函数(YEAR()、MONTH())配合分区键,实现分区裁剪,只扫描部分分区,避免全表扫描。
前提:分区键就是该字段,函数用于分区逻辑,不要在 where 索引列套函数做过滤。
4. 复杂逻辑、多表合并,替代应用层循环(控制流、字符串函数)
IF()、CASE WHEN、COALESCE(),在 SQL 内部完成分支判断、空值处理。 场景:多字段条件判断、多来源字段择优输出,避免查询出数据后在业务代码做 if‑else 循环。
SELECT order_id,COALESCE(pay_time,create_time) AS effective_time FROM t_order;
✅收益:减少应用层循环遍历,一次 SQL 输出业务需要的结果。
5. JSON 字段内置函数(MySQL JSON、PostgreSQL jsonb)
使用数据库原生 JSON 函数JSON_EXTRACT、->>,直接在库内提取 JSON 内部字段,过滤、投影。
对比:查出完整 JSON 字符串,拉到应用代码解析,会消耗大量内存与 CPU。
SELECT json->>'$.name' FROM t_info WHERE json->>'$.age' >18;
进阶:JSON 列创建索引,JSON 函数过滤也可以走索引。
6. 窗口函数(MySQL8.0 / PostgreSQL)
ROW_NUMBER()、RANK()、PARTITION BY,替代子查询、自连接、应用层分页排序。 典型场景:分组取 topN、同组最新一条、行内排名。
旧写法:多次子查询、关联,性能差;
窗口函数:一次扫描完成分组排序,减少表扫描次数。
-- 每个用户取最新一笔订单,窗口函数实现
SELECT * FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY create_time DESC) rn
FROM t_order
) t WHERE rn=1;
✅收益:大幅减少表扫描次数,替代 N 次关联子查询。
7. 数学函数、加密校验(库内计算)
数值运算、哈希校验,数据库侧直接计算过滤,避免大量数据传出。
二、⚠️ 绝对要避开:函数写在 WHERE 条件索引列上(最常见坑)
-- ❌ 索引失效!对索引列使用函数,无法使用B+树索引,触发全表扫描
SELECT * FROM t_order WHERE DATE(create_time) = '2026‑08‑23';
原理:对列做函数运算,索引存储原始值,无法匹配运算后的值;无法走普通 B + 树索引。
✅改写方案:把函数挪到常量侧,保留字段裸写
SELECT * FROM t_order WHERE create_time >= '2026‑08‑23 00:00:00' AND create_time < '2026‑08‑24 00:00:00';
例外:MySQL 支持函数索引 (表达式索引),可以针对
DATE(create_time)建索引,此时 where 条件使用函数可以命中索引。
三、总结:什么时候用函数能优化效率
核心经验
函数放 SELECT,不要随便放 WHERE 的索引字段;
把计算下压数据库,减少网络 IO和应用层循环处理,是函数优化查询的核心;
WHERE 条件一定要用函数,优先考虑创建函数索引 / 表达式索引;
窗口函数优先用来替换复杂子查询、分组取 topN 场景,性能提升非常明显。
本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢