问题描述

优化过程中遇到一个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. poi基本使用

    poi基本使用 依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi< ...

  2. c# 笔试面试题01

    一.抽象与接口的区别: ,抽象(abstract): ()抽象类中可以有抽象方法,也可没有: ()抽象方法包含实现,也可以由子类实现: ()抽象类不能被sealed修饰,只能使用abstract关键字 ...

  3. k8s学习路线

    1. 核心概念说明 http://dockone.io/article/932 https://www.centos.bz/2017/08/k8s-kubernetes-architecture-di ...

  4. DirectX:Vector

    Tag DirectX下的博客主要用于记录DirectX的学习过程,主要参考<DirectX 12 3D 游戏实战开发>. Vector in DirectX Shader的编写离不开数学 ...

  5. windows 的一些快捷键

    https://www.zhihu.com/question/276786944/answer/698967240 1.新建文件夹 Ctrl  + Shift + N        或者鼠标右键 然后 ...

  6. CAS5单点登录

    看这篇文章即可:https://www.jianshu.com/p/c1273d81c4e4>https://www.jianshu.com/p/c1273d81c4e4

  7. 循环节 + 矩阵快速幂 - HDU 4291 A Short problem

    A Short problem Problem's Link Mean: 给定一个n,求:g(g(g(n))) % 1000000007 其中:g(n) = 3g(n - 1) + g(n - 2), ...

  8. Spring Boot2.0以上版本EmbeddedServletContainerCustomizer被WebServerFactoryCustomizer替代

    在Spring Boot2.0以上配置嵌入式Servlet容器时EmbeddedServletContainerCustomizer类不存在,经网络查询发现被WebServerFactoryCusto ...

  9. Git系列四之在本地服务器搭建gitlab仓库管理(centeros环境下)

    1.Git仓库管理 现在本地已经创建了git仓库,又在gitlab上创建了一个git仓库,并且让这两个仓库进行远程同步,这样gitlab仓库既可以备份也可以与他人协作管理远程仓库以及根据需要推送或拉取 ...

  10. 【UOJ#32】【UR #2】跳蚤公路(最短路)

    [UOJ#32][UR #2]跳蚤公路(最短路) 题面 UOJ 题解 不难发现要求的就是是否存在负环.也就是我们只需要找到所有的负的简单环,很容易就可以想到维护路径上和\(x\)相关的内容,即维护一下 ...