存储函数不提升性能,反而可能拖慢查询;应仅用于逻辑固定、参数简单、结果确定、调用频繁的场景,如格式化输出、业务规则判断、轻量映射和权限辅助计算,并严格遵守deterministic声明、避免基表查询、参数类型匹配三条铁律。

SQL 存储函数本身不直接提升性能,反而可能拖慢查询——关键在“何时用、怎么写、如何规避陷阱”。盲目封装逻辑进函数,常导致执行计划失效、无法下推条件、隐式转换和重复计算。
哪些场景适合用存储函数
真正适合封装成存储函数的,是那些逻辑固定、参数简单、结果确定、调用频次高的计算任务:
- 格式化输出:如将毫秒时间戳转为“YYYY-MM-DD HH:MM”字符串(MySQL 的
FROM_UNIXTIME封装) - 业务规则判断:如判断订单金额是否满足免运费阈值(返回 TINYINT 或 BOOLEAN)
- 轻量数据映射:如根据状态码返回中文描述(
CASE WHEN封装,避免 SQL 中重复写) - 权限辅助计算:如判断当前用户对某资源是否有读权限(仅查缓存表或小维度表)
⚠️ 避免用于:涉及大表 JOIN、子查询、动态 SQL、临时表、事务控制、或返回结果集(应改用存储过程)。
写法上必须遵守的三条铁律
违反任一条,都可能让优化器“放弃治疗”:
本文档主要讲述的是android rtsp流媒体播放介绍;实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。数据源包括现场数据与存储在剪辑中数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径,并为选择基于RTP上发送机制提供方法。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
-
声明 DETERMINISTIC:若函数逻辑不依赖外部状态(如 NOW()、USER()、系统变量),必须显式标注,否则 MySQL 默认视为
NOT DETERMINISTIC,禁止在索引列、分区表达式等场景使用 - 避免 SELECT 查询访问基表:函数内查主业务表 = 每行调用都触发一次查询。改为提前 JOIN 或用派生表预计算
-
参数类型与字段严格匹配:例如字段是
VARCHAR(32),函数参数别写CHAR或TEXT,否则引发隐式类型转换,导致索引失效
替代方案往往更高效
多数所谓“需要函数”的需求,用原生 SQL 或物化手段更优:
- 复杂计算 → 改用
CASE WHEN+ 表达式,让优化器全程可见、可下推、可并行 - 多步转换 → 提前在 ETL 或应用层处理,或建计算列(MySQL 5.7+ 支持
STORED虚拟列并建索引) - 频繁复用逻辑 → 抽成视图(简单逻辑)或 CTE(复杂但单次执行),比函数调用开销低得多
- 跨库/跨服务逻辑 → 移到应用层统一维护,数据库只做纯粹的数据存取
必须做的性能验证动作
上线前跑三步,少一步都可能线上翻车:
- 用
EXPLAIN FORMAT=JSON对比加函数前后的执行计划,重点看filtered是否骤降、是否出现Using temporary或Using filesort - 开启
profiling(MySQL)或pg_stat_statements(PostgreSQL),实测函数调用本身的耗时占比(>10% 就该重构) - 压测时监控 CPU 和 Buffer Pool 命中率:函数内频繁查小表可能把热数据挤出缓存
不复杂但容易忽略。










