详解Mysql 函数调用优化


Posted in MySQL onApril 07, 2021

函数调用优化

MySQL函数在内部被标记为确定性或不确定性。如果给定参数固定值的函数可以为不同的调用返回不同的结果,则它是不确定的。不确定函数的示例: RAND()UUID()

如果某个函数被标记为不确定的,则将WHERE针对每一行(从一个表中选择时)或行的组合(从多表联接中选择时)评估子句中对该函数的引用。

MySQL还根据参数的类型(参数是表列还是常量值)确定何时评估函数。每当表列更改值时,都必须评估将表列作为参数的确定性函数。

非确定性函数可能会影响查询性能。例如,某些优化可能不可用,或者可能需要更多锁定。以下讨论使用 RAND()但也适用于其他不确定性函数。

假设一个表t具有以下定义:

CREATE TABLE t (id INT NOT NULL PRIMARY KEY, col_a VARCHAR(100));

考虑以下两个查询:

SELECT * FROM t WHERE id = POW(1,2);
SELECT * FROM t WHERE id = FLOOR(1 + RAND() * 49);

由于与主键的相等性比较,两个查询似乎都使用了主键查找,但这仅适用于第一个查询:

  • 第一个查询始终最多产生一行,因为POW()带有常量参数的常量是一个常量值,并用于索引查找。
  • 第二个查询包含一个使用非确定性函数的表达式,该表达式 RAND()在查询中不是常量,但实际上对表的每一行都有一个新值t。因此,查询读取表的每一行,评估每一行的谓词,并输出主键与随机值匹配的所有行。根据id列值和RAND()序列中的值, 它可以是零行,一行或多行 。

非确定性的影响不仅限于 SELECT陈述。该 UPDATE语句使用非确定性函数来选择要修改的行:

UPDATE t SET col_a = some_expr WHERE id = FLOOR(1 + RAND() * 49);

大概目的是最多更新主键与表达式匹配的一行。但是,它可能会更新零,一或多个行,具体取决于 id列值和RAND()序列中的值 。

刚刚描述的行为对性能和复制有影响:

  • 由于不确定函数不会产生恒定值,因此优化器无法使用其他可能适用的策略,例如索引查找。结果可能是表扫描。
  • InnoDB 可能升级为范围键锁,而不是为一个匹配的行获取单行锁。
  • 无法确定执行的更新对于复制是不安全的。

困难源于RAND()对表的每一行都对函数进行一次评估的事实 。为了避免进行多功能评估,请使用以下技术之一:

  • 将包含不确定性函数的表达式移到单独的语句,将值保存在变量中。在原始语句中,将表达式替换为对变量的引用,优化器可以将该变量视为常量值:
SET @keyval = FLOOR(1 + RAND() * 49);
UPDATE t SET col_a = some_expr WHERE id = @keyval;
  • 将随机值分配给派生表中的变量。此技术使变量在WHERE子句中的比较中使用之前被分配一个值 :
SET optimizer_switch = 'derived_merge=off';
UPDATE t, (SELECT @keyval := FLOOR(1 + RAND() * 49)) AS dt
SET col_a = some_expr WHERE id = @keyval;

如前所述,该WHERE子句中的不确定性表达式 可能会阻止优化并导致表扫描。但是,WHERE如果其他表达式是确定性的,则可以部分优化该子句。例如:

SELECT * FROM t WHERE partial_key=5 AND some_column=RAND();

如果优化器可以partial_key用来减少所选行的集合, RAND()则执行的次数更少,这可以减少不确定性对优化的影响。

以上就是详解Mysql 函数调用优化的详细内容,更多关于Mysql 函数调用优化的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
mysql知识点整理
Apr 05 MySQL
MySQL 聚合函数排序
Jul 16 MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
Oct 16 MySQL
MYSQL 运算符总结
Nov 11 MySQL
MySQL之MyISAM存储引擎的非聚簇索引详解
Mar 03 MySQL
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
Mar 23 MySQL
你真的会用Mysql的explain吗
Mar 31 MySQL
一文简单了解MySQL前缀索引
Apr 03 MySQL
MySQL创建管理KEY分区
Apr 13 MySQL
Mysql 如何合理地统计一个数据库里的所有表的数据量
Apr 18 MySQL
MySQL 数据库范式化设计理论
Apr 22 MySQL
mysql 获取相邻数据项
May 11 MySQL
MySQL复制问题的三个参数分析
Apr 07 #MySQL
MySQL pt-slave-restart工具的使用简介
Apr 07 #MySQL
MySQL主从复制断开的常用修复方法
Apr 07 #MySQL
MySQL infobright的安装步骤
Apr 07 #MySQL
MySQL表的增删改查基础教程
mysql批量新增和存储的方法实例
Apr 07 #MySQL
Mysql 性能监控及调优
You might like
Apache 配置详解(最好的APACHE配置教程)
2010/07/04 PHP
那些年一起学习的PHP(二)
2012/03/21 PHP
浅析linux下apache服务器的配置和管理
2013/08/10 PHP
php版微信公众平台开发之验证步骤实例详解
2016/09/23 PHP
PHP自定义函数判断是否为Get、Post及Ajax提交的方法
2017/07/27 PHP
PHP PDOStatement::getAttribute讲解
2019/02/01 PHP
如何在centos8自定义目录安装php7.3
2019/11/28 PHP
彪哥1.1(智能表格)提供下载
2006/09/07 Javascript
JS跨域代码片段
2012/08/30 Javascript
js实现屏蔽默认快捷键调用自定义事件示例
2013/06/18 Javascript
jquery实现滑动图片自己测试的例子
2013/11/05 Javascript
将中国标准时间转换成标准格式的代码
2014/03/20 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
js实现图片切换(动画版)
2016/12/25 Javascript
微信小程序 详解页面跳转与返回并回传数据
2017/02/13 Javascript
自定义PC微信扫码登录样式写法
2017/12/12 Javascript
node.js ws模块搭建websocket服务端的方法示例
2019/04/25 Javascript
p5.js实现动态图形临摹
2019/10/23 Javascript
vue动态加载SVG文件并修改节点数据的操作代码
2020/08/17 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
[59:36]2018DOTA2亚洲邀请赛 4.3 突围赛 Secret vs VG 第二场
2018/04/04 DOTA
python操作日期和时间的方法
2014/03/11 Python
Python快速转换numpy数组中Nan和Inf的方法实例说明
2019/02/21 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
python tornado使用流生成图片的例子
2019/11/18 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
2019/12/04 Python
pytorch之ImageFolder使用详解
2020/01/06 Python
极简的HTML5模版
2015/07/09 HTML / CSS
你在项目中用到了xml技术的哪些方面?如何实现的?
2014/01/26 面试题
幼儿园家长安全责任书
2014/07/22 职场文书
2014坚持党风廉政建设思想汇报
2014/09/18 职场文书
商务宴请邀请函范文
2015/02/02 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
jquery插件实现图片悬浮
2021/04/16 jQuery
Go 语言中 20 个占位符的整理
2021/10/16 Golang
尝试使用Python爬取城市租房信息
2022/04/12 Python