0

0

SQL 中函数调用的代价分析

冷炫風刃

冷炫風刃

发布时间:2026-01-25 19:49:02

|

724人浏览过

|

来源于php中文网

原创

会,标量函数(如UPPER、CONVERT)在WHERE中逐行计算且阻断索引;ITVF可展开优化,MSTVF和UDF易致统计丢失、序列化执行;应避免列上函数,改用参数端转换或常量替换。

sql 中函数调用的代价分析

SQL 函数调用会拖慢查询吗? 会,但取决于函数类型和使用方式。标量函数(如 UPPER()DATEADD())在 WHERE 或 SELECT 中对每行逐个计算,可能阻断索引下推、抑制并行执行,甚至让优化器放弃估算。而内联表值函数(ITVF)通常可展开为等价 SQL,代价接近原生查询;多语句表值函数(MSTVF)则像黑盒,常导致统计信息丢失和嵌套循环连接。

WHERE 子句里用 CONVERT()CAST() 为什么查得慢? 这类显式转换常出现在“把字段转成字符串再模糊匹配”场景,例如:WHERE CAST(order_id AS VARCHAR) LIKE '123%'。问题在于:
  • 字段被函数包裹后,无法走 order_id 列上的索引(即使该列是整型主键)
  • SQL Server 无法对转换结果生成有效统计直方图,优化器容易低估/高估行数
  • 如果 order_id 是聚集索引键,强制转换还会阻止范围扫描,退化为全索引扫描
更稳妥的做法是反向转换:把参数转为目标列类型,例如 WHERE order_id >= 12300 AND order_id (若业务允许前缀数字解析)。

GETDATE()SYSDATETIME() 在 WHERE 中能用索引吗? 可以,但仅限于“列 >= 函数调用”这类单调递增表达式。例如:WHERE created_at >= GETDATE() - 1,优化器能将函数求值一次后转为常量,再配合 created_at 上的索引做范围查找。但以下写法会失效:
  • WHERE DATEDIFF(day, created_at, GETDATE()) = 0 —— 函数包裹列,索引失效
  • WHERE YEAR(created_at) = YEAR(GETDATE()) —— 同样破坏 sargability
注意:GETDATE() 是运行时标量函数,每次执行只算一次(非每行),但只要它让谓词不可 SARGable,索引就白搭。

自定义标量函数(UDF)为何比内置函数更危险? SQL Server 2019 之前,UDF 默认被当作“黑盒”,优化器既不内联也不推导其行为,哪怕函数体只有一行 RETURN @x + 1。后果包括:
  • 强制序列化执行(禁用并行)
  • 每行调用一次,且无法复用中间结果(无缓存)
  • 执行计划中显示为 Compute Scalar,但实际开销常被严重低估
SQL Server 2019+ 启用 QUERY_OPTIMIZER_HOTFIXES 或数据库兼容级别 ≥ 150 后,部分简单 UDF 可自动内联——但必须满足:无副作用、无引用对象、无分支逻辑。否则仍退化为旧模式。

函数代价最隐蔽的地方不在 CPU,而在执行计划失真:你以为只是加了个 LEN(),结果优化器选了嵌套循环而非哈希连接,最后扫了千万行才出结果。别信“这个函数很简单”,先看执行计划里的 Actual Row Count 和 Operator Cost 分布。

华友协同办公自动化OA系统
华友协同办公自动化OA系统

华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、

下载

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

686

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

325

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1159

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

359

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

757

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

577

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

420

2024.04.29

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

45

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 0.7万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号