MySQL Execution Plan--合理利用隐式的业务逻辑
问题描述
优化过程中遇到一个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--合理利用隐式的业务逻辑的更多相关文章
- android 利用隐式Intent打开图片
实现功能 点击"查看图片"时能够跳出提示,选择系统图库打开还是自己编写的应用打开,并且对于下载好的图片也有效. 1.我将 qiaoba.jpg 放在 res/drawable ...
- MySQL隐式转化整理
MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...
- mysql的隐式转化
MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...
- MySQL的隐式类型转换整理总结
当我们对不同类型的值进行比较的时候,为了使得这些数值「可比较」(也可以称为类型的兼容性),MySQL会做一些隐式转化(Implicit type conversion). 比如下面的例子: 1 2 ...
- 每天多一点(2016.12.04)》Javascript隐式转换
乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...
- Javascript隐式转换
乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Scala学习之路 (八)Scala的隐式转换和隐式参数
一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...
- 【RS】BPR:Bayesian Personalized Ranking from Implicit Feedback - BPR:利用隐反馈的贝叶斯个性化排序
[论文标题]BPR:Bayesian Personalized Ranking from Implicit Feedback (2012,Published by ACM Press) [论文作者]S ...
随机推荐
- zz模型剪枝
论文总结 - 模型剪枝 Model Pruning 发表于 2018-10-03 模型剪枝是常用的模型压缩方法之一.这篇是最近看的模型剪枝相关论文的总结. Deep Compression, Han ...
- LeetCode 113. Path Sum II路径总和 II (C++)
题目: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the give ...
- JAVA基础概念(三)
JAVA方法入参和返回类型 方法入参 基础数据类型 引用数据类型 修饰符 返回类型 方法名(参数类型 参数名,参数类型 参数名...){//方法体return} 方法返回类型 return xxx 具 ...
- numpy cookbook
1.第一章 import numpy as np import matplotlib.pyplot as plt import scipy import PIL import scipy.misc l ...
- wait函数和waitpid的使用和总结
wait和waitpid出现的原因 SIGCHLD --当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) --子进程退出时,内 ...
- 【CFGym102059G】Fascination Street(思维DP)
点此看题面 大致题意: 有\(n\)个路灯,每个路灯有一定的建造费用,且建成后可照亮自身及周围距离为\(1\)的两个格子.你可以交换\(k\)次两个路灯的建造费用,求照亮所有格子的最小费用. 题意转换 ...
- A1050 String Subtraction (20 分)
一.技术总结 这个是使用了一个bool类型的数组来判断该字符是否应该被输出. 然后就是如果在str2中出现那么就判断为false,被消除不被输出. 遍历str1如果字符位true则输出该字符. 还有需 ...
- [LeetCode] 2. Add Two Numbers 两个数字相加
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- git合并不同仓库下的分支
1.把lib合并到pro $ git remote -v origin git@192.168.1.1:lib.git (fetch) origin git@192.168.1.1:lib.git ( ...
- React Hooks 深入系列
本文基于近段时间对 hooks 碎片化的理解作一次简单梳理, 个人博客.同时欢迎关注基于 hooks 构建的 UI 组件库 -- snake-design. 在 class 已经融入 React 生态 ...