详解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 14 MySQL
详解MySQL的Seconds_Behind_Master
May 18 MySQL
MySQL大小写敏感的注意事项
May 24 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
MySQL一些常用高级SQL语句
Jul 03 MySQL
Mysql存储过程、触发器、事件调度器使用入门指南
Jan 22 MySQL
面试提问mysql一张表到底能存多少数据
Mar 13 MySQL
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
Mar 22 MySQL
提高系统的吞吐量解决数据库重复写入问题
Apr 23 MySQL
MySQL的存储过程和相关函数
Apr 26 MySQL
MySQL数据库 任意ip连接方法
May 20 MySQL
mysql实现将字符串字段转为数字排序或比大小
Jun 14 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
php下实现一个阿拉伯数字转中文数字的函数
2008/07/10 PHP
php判断字符以及字符串的包含方法属性
2008/08/30 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
php判断当前操作系统类型
2015/10/28 PHP
深入浅析php中sprintf与printf函数的用法及区别
2016/01/08 PHP
PHP性能优化大全(php.ini)
2016/05/20 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
2010/10/01 Javascript
图标线性回归斜着移动到指定的位置
2013/08/16 Javascript
js定义类的几种方法(推荐)
2016/06/08 Javascript
详解用node编写自己的cli工具
2017/05/23 Javascript
React Native 环境搭建的教程
2017/08/19 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
vue基于better-scroll实现左右联动滑动页面
2020/06/30 Javascript
[02:27]刀塔重生降临
2015/10/14 DOTA
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
python使用PyGame播放Midi和Mp3文件的方法
2015/04/24 Python
python实现list元素按关键字相加减的方法示例
2017/06/09 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
2017/07/04 Python
Python中的单继承与多继承实例分析
2018/05/10 Python
Python 获取指定文件夹下的目录和文件的实现
2019/08/30 Python
解决tensorflow打印tensor有省略号的问题
2020/02/04 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
台湾演唱会订票网站:StubHub台湾
2019/06/11 全球购物
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
大专生自我鉴定范文
2013/10/01 职场文书
教师研修随笔感言
2014/01/23 职场文书
市场营销专业毕业生求职信
2014/07/21 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
离婚财产分隔协议书
2014/10/23 职场文书
《月光曲》教学反思
2016/02/16 职场文书
2019自荐信该如何写呢?
2019/07/05 职场文书
《工作是最好的修行》读后感3篇
2019/12/13 职场文书
react合成事件与原生事件的相关理解
2021/05/13 Javascript
Win11使用CAD卡顿或者致命错误怎么办?Win11无法正常使用CAD的解决方法
2022/07/23 数码科技