查看“函数调用优化”的源代码
←
函数调用优化
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
MySQL函数在内部被标记为确定性或不确定性。如果一个函数在给定参数的固定值的情况下,对于不同的调用可以返回不同的结果,则该函数是不确定性的。不确定性函数的例子包括:RAND()、UUID()。 如果一个函数被标记为不确定性,那么在WHERE子句中对它的引用将会对每一行(当从一个表中选择)或每一组行(当从多个表联接中选择)进行评估。 MySQL还根据参数的类型(是否为表列或常量值)来确定何时评估函数。如果一个确定性函数以表列作为参数,那么每当该列的值发生变化时,就必须进行评估。 不确定性函数可能会影响查询性能。例如,有些优化可能不可用,或者需要更多的锁定。下面的讨论以RAND()为例,但同样适用于其他不确定性函数。 假设一个表t有如下定义: <pre>CREATE TABLE t (id INT NOT NULL PRIMARY KEY, col_a VARCHAR(100));</pre> 考虑以下两个查询: SELECT * FROM t WHERE id = POW(1,2); SELECT * FROM t WHERE id = FLOOR(1 + RAND() * 49); 这两个查询似乎都使用了主键查找,因为它们与主键进行了等值比较,但实际上只有第一个查询是这样的: * 第一个查询总是最多产生一行,因为具有常量参数的POW()是一个常量值,并用于索引查找。 * 第二个查询包含一个使用非确定性函数RAND()的表达式,在查询中不是常量,实际上对于表t的每一行都有一个新值。因此,查询读取表的每一行,对每一行计算谓词,并输出与随机值匹配的所有行。这可能是零行、一行或多行,这取决于id列的值和RAND()序列中的值。 非确定性的影响不仅限于SELECT语句。此UPDATE语句使用非确定性函数来选择要修改的行: <pre>UPDATE t SET col_a = some_expr WHERE id = FLOOR(1 + RAND() * 49);</pre> 可能的意图是更新与表达式匹配的最多一行。然而,它可能会更新零行、一行或多行,这取决于id列的值和RAND()序列中的值。 上述描述的行为对性能和复制产生了影响: * 由于非确定性函数不能产生一个常量值,优化器不能使用可能适用的策略,如索引查找。结果可能是一个表扫描。 * InnoDB可能会升级为范围键锁,而不是为一个匹配行获取单个行锁。 * 在复制中,不执行确定性更新是不安全的。 困难源于RAND()函数对表的每一行都进行了一次计算。为避免多次函数计算,可以使用以下其中一种技术: <ul> <li><p>将包含非确定性函数的表达式移动到单独的语句中,并将值保存在变量中。在原始语句中,用对变量的引用替换表达式,优化器可以将其视为常量值:</p> <pre> SET @keyval = FLOOR(1 + RAND() * 49); UPDATE t SET col_a = some_expr WHERE id = @keyval;</pre></li> <li><p>将随机值赋给派生表中的一个变量。这种技术使变量在使用WHERE子句中的比较之前被分配了一个值,仅仅一次:</p> <pre> UPDATE /*+ NO_MERGE(dt) */ t, (SELECT FLOOR(1 + RAND() * 49) AS r) AS dt SET col_a = some_expr WHERE id = dt.r;</pre></li></ul> 正如之前提到的,WHERE子句中的非确定性表达式可能会阻止优化,并导致表扫描。然而,如果其他表达式是确定性的,可能可以部分优化WHERE子句。例如: <pre>SELECT * FROM t WHERE partial_key=5 AND some_column=RAND();</pre> 如果优化器可以使用partial_key来减少所选行的集合,则RAND()的执行次数较少,这降低了非确定性对优化的影响。
返回至“
函数调用优化
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
基础知识
正则表达式
Markdown
分布式
项目管理
系统集成项目管理基础知识
云原生
Docker
云原生安全
云原生词汇表
十二因素应用
Kubernetes
音频处理
音频合成
Edge-tts
CMS系统
Docsify
VuePress
Mediawiki
自动生成
Marp
CI/CD
GitLab
设计
颜色
平面设计
AI
数字人
操作系统
GNU/Linux
数据库
Mysql
工具
链入页面
相关更改
特殊页面
页面信息