详解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数据库中存入汉字报错的方法
May 06 MySQL
MySQL触发器的使用
May 24 MySQL
MySQL中VARCHAR与CHAR格式数据的区别
May 26 MySQL
MySQL 数据恢复的多种方法汇总
Jun 21 MySQL
mysql联合索引的使用规则
Jun 23 MySQL
MySQL千万级数据表的优化实战记录
Aug 04 MySQL
教你如何让spark sql写mysql的时候支持update操作
Feb 15 MySQL
Pycharm远程调试和MySQL数据库授权问题
Mar 18 MySQL
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
Apr 09 MySQL
MySQL数据库优化之通过索引解决SQL性能问题
Apr 10 MySQL
MySQL数据库 安全管理
May 06 MySQL
MySQL数据库之存储过程 procedure
Jun 16 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
文件上传的实现
2006/10/09 PHP
PHP中HTML标签过滤技巧
2014/01/07 PHP
php利用新浪接口查询ip获取地理位置示例
2014/01/20 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
浏览器常用高宽的jquery插件
2011/02/24 Javascript
ExtJs Excel导出并下载IIS服务器端遇到的问题
2011/09/16 Javascript
js限制文本框只能输入数字方法小结
2014/06/16 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
js实现顶部可折叠的菜单工具栏效果实例
2015/05/09 Javascript
基于JavaScript实现回到页面顶部动画代码
2016/05/24 Javascript
JS修改地址栏参数实例代码
2016/06/14 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
2018/03/17 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
vue项目中使用lib-flexible解决移动端适配的问题解决
2018/08/23 Javascript
vue组件三大核心概念图文详解
2019/05/30 Javascript
解决Vue打包后访问图片/图标不显示的问题
2019/07/25 Javascript
JS/CSS实现字符串单词首字母大写功能
2019/09/03 Javascript
Vue学习之axios的使用方法实例分析
2020/01/06 Javascript
Python的dict字典结构操作方法学习笔记
2016/05/07 Python
Python基于list的append和pop方法实现堆栈与队列功能示例
2017/07/24 Python
python中列表和元组的区别
2017/12/18 Python
pandas ix &iloc &loc的区别
2019/01/10 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
python 列表输出重复值以及对应的角标方法
2019/06/11 Python
瑜伽国际:Yoga International
2018/04/18 全球购物
尼克松手表官网:Nixon手表
2019/03/17 全球购物
SQL中where和having的区别
2012/06/17 面试题
广告学专业毕业生自荐信
2013/09/24 职场文书
销售自荐信
2013/10/22 职场文书
个人三严三实对照检查材料思想汇报
2014/09/22 职场文书
党的群众路线整改落实情况汇报
2014/10/28 职场文书
2015年健康教育工作总结
2015/04/10 职场文书
2015年政风行风工作总结
2015/04/21 职场文书
浅谈redis的过期时间设置和过期删除机制
2022/03/18 MySQL