问题描述

优化过程中遇到一个SQL:

SELECT
SUM(user_value)
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1;

其执行计划为:

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_log
partitions: NULL
type: ref
possible_keys: index_sId_ty_vl_ct,IDX_product_id_oth1
key: IDX_product_id_oth1
key_len: 12
ref: const,const,const
rows: 14884
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec

从执行计划来看,使用Using index(覆盖索引)已经是最优的执行计划,但每次查询扫描数据较多,影响整体查询性能。

优化方案

查询需要使用SUM计算user_value的总和,借用1+1+0+0+0+0+0=1+1=2的例子,进行如下测试:

SELECT
SUM(CASE WHEN user_value>0 THEN 1 ELSE 0 END) AS count1,
COUNT(1) AS count2
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1; +--------+--------+
| count1 | count2 |
+--------+--------+
| 680 | 8067 |
+--------+--------+

在假设user_value没有负值的情况下,下面两条SQL的结果相同:

##测试SQL1
SELECT
SUM(user_value),
COUNT(1) AS count2
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1; ##测试SQL2
SELECT
SUM(user_value)
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1
AND user_value>0;

测试SQL1的执行时间为0.00327250,其资源消耗为:

+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting | 0.000066 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| checking permissions | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Opening tables | 0.000016 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| init | 0.000021 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| System lock | 0.000015 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| optimizing | 0.000016 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| statistics | 0.000127 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| preparing | 0.000019 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| executing | 0.000011 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Sending data | 0.002867 | 0.002999 | 0.000000 | 0 | 0 | 0 |
| end | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| query end | 0.000013 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| closing tables | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| freeing items | 0.000054 | 0.000000 | 0.000000 | 0 | 8 | 0 |
| cleaning up | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+

而测试SQL2的执行时间为0.00072325,其资源消耗为:

+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting | 0.000072 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| checking permissions | 0.000013 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Opening tables | 0.000016 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| init | 0.000021 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| System lock | 0.000014 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| optimizing | 0.000020 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| statistics | 0.000089 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| preparing | 0.000020 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| executing | 0.000011 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| Sending data | 0.000365 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| end | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| query end | 0.000014 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| closing tables | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| freeing items | 0.000035 | 0.000000 | 0.000000 | 0 | 0 | 0 |
| cleaning up | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+

在Sending data部分,两者在Durion部分差距约10倍,而测试SQL2在CPU_user部分差距更明显。

总结:

DBA在优化SQL时,除了从数据分布/索引结构等方面入手外,还需要从业务逻辑方面入手。

PS:上面的优化是假设user_value没有负值,而实际业务逻辑中user_value可能存在负值,因此以上优化纯属于瞎编。

MySQL Execution Plan--合理利用隐式的业务逻辑的更多相关文章

  1. android 利用隐式Intent打开图片

    实现功能   点击"查看图片"时能够跳出提示,选择系统图库打开还是自己编写的应用打开,并且对于下载好的图片也有效. 1.我将 qiaoba.jpg 放在 res/drawable  ...

  2. MySQL隐式转化整理

    MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...

  3. mysql的隐式转化

    MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...

  4. MySQL的隐式类型转换整理总结

    当我们对不同类型的值进行比较的时候,为了使得这些数值「可比较」(也可以称为类型的兼容性),MySQL会做一些隐式转化(Implicit type conversion). 比如下面的例子:   1 2 ...

  5. 每天多一点(2016.12.04)》Javascript隐式转换

    乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...

  6. Javascript隐式转换

    乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...

  7. Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  8. Scala学习之路 (八)Scala的隐式转换和隐式参数

    一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...

  9. 【RS】BPR:Bayesian Personalized Ranking from Implicit Feedback - BPR:利用隐反馈的贝叶斯个性化排序

    [论文标题]BPR:Bayesian Personalized Ranking from Implicit Feedback (2012,Published by ACM Press) [论文作者]S ...

随机推荐

  1. OpenVINO 目标检测底层C++代码改写实现(待优化)

    System: Centos7.4 I:OpenVINO 的安装 refer:https://docs.openvinotoolkit.org/latest/_docs_install_guides_ ...

  2. openLayers绘制静态底图

    由于项目需要,需要是使用openlayers框架,于是开始安利一波openlayers,可以点击 https://openlayers.org/   进入他的官网下载相关资源和案例 学习的过程总是慢慢 ...

  3. 【Mybatis】多个参数如何写xml和mapper

    1:#{0},#{1}  不写parameterType 2:注解 @Param("id")String id 3:Map   parameterType="hashma ...

  4. 卷积神经网络以及TextCNN

    对于卷积神经网络的详细介绍和一些总结可以参考以下博文: https://www.cnblogs.com/pinard/p/6483207.html https://blog.csdn.net/guoy ...

  5. docker的一些常用操作

    镜像:一个打包好的应用,还有应用运行的系统.资源.配置等容器:镜像的实例,一个镜像可以有一个或多个实例(容器)对docker容器的变更时写到容器的文件系统的,而不是写到docker镜像中的,可以用一个 ...

  6. 认识map-reduce

    基本概念 map-reduce1.0 例子: hadoop streaming 用语言驱动map-reduce的话,使用的hadoop streaming命令,可以通过python,php,java来 ...

  7. java语言规范

    一.标志符 命名规则: 标识符由26个英文字符大小写(a~zA~Z).数字(0~9).下划线(_)和美元符号($)组成. 不能以数字开头,不能是关键字 严格区分大小写 标识符的可以为任意长度 命名规范 ...

  8. Win10 1903 运行安卓模拟器蓝屏解决方案

    由于没有安卓机,想要测试一些东西,所以选择了安卓模拟器,可是一运行模拟器就导致电脑蓝屏,试了 N 次都不行. 于是在网上寻找解决方案,了解到导致蓝屏的原因都是因为虚拟化技术,我的系统是 Windows ...

  9. Consul 使用手册(感觉比较全了)

    HTTP API consul的主要接口是RESTful HTTP API,该API可以用来增删查改nodes.services.checks.configguration.所有的endpoints主 ...

  10. 【转】PyQt弹出式对话框的常用方法及标准按钮类型

    pyQt之弹出式对话框(QMessageBox)的常用方法及标准按钮类型 一.控件说明 QMessageBox是一种通用的弹出式对话框,用于显示消息,允许用户通过单击不同的标准按钮对消息进行反馈,且每 ...