问题描述

优化过程中遇到一个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. JDOJ 2255 A+B Problem

    JDOJ 2255: A+B Problem https://neooj.com/oldoj/problem.php?id=2255 Description Solve A+B problem wit ...

  2. 团队冲刺--three

    今天学习css,用css做登录界面. 昨天学习了爬虫了初步. 问题:爬虫很难.

  3. beeline无密码连接hiveserver2

    1.说明 #hiveserver2增加了权限控制,需要在hadoop的配置文件中配置 core-site.xml 增加以下内容: <property> <name>hadoop ...

  4. windows7 - windows10开启802.1x md5质询

    (win7 win10通用)20190324   全程不需重启 注:如果导入后没有看到md5,那得去注册表看看是否真的有键值(我的一开始提示成功,但是注册表里看不到,后来发现复制时候多了一些不可见的字 ...

  5. 转 A 、B两张表,找出ID字段中,存在A表,但是不存在B表的数据

    A.B两张表,找出ID字段中,存在A表,但是不存在B表的数据,A表总共13W数据,去重后大约3万条数据,B表有2W条数据,且B表的ID有索引. 方法一 使用not in,容易理解,效率低. selec ...

  6. 微信企业号JS SDK

    微信企业号JS SDK <?php define('CorpID', "wx82e2c31215d9a5a7"); define('CorpSecret', "&q ...

  7. django实战(五)--增加数据

    urls.py urlpatterns=[ path('curd/add/',views.curd_add,name='curdadd'), path('curd/saveadd/',views.cu ...

  8. Python【每日一问】38

    问: 基础题: 设计一个经营杠杆系数函数DOL,它包含三个参数,S为营业收入,C为变动成本总额,F为固定成本的总额. 已知2018年的S为20,C为11,F为3,求2019年的经营杠杆系数. 提高题: ...

  9. vue表单验证不通过,依然能执行点击事件里面的代码?

    遇到的问题:表单提交的时候,写了rules,明明验证不通过依然执行了点击事件里面的代码. 这个验证有什么用? 后来 我看elementUI组件才发现,我漏写了几行代码. methods里面这样写 完美 ...

  10. 【排错】springboot项目,启动报An attempt was made to call the method com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder; but it does not exist.

    pom文件新引入:     <dependency>         <groupId>com.google.code.gson</groupId>         ...