此篇只是个人记录,相信各位大神早已轻车熟路,不喜勿喷;有错之处,欢迎指正。

有一天收到新人的咨询,是关于sql的问题。

问题1:为什么sql查询的数据与界面展示的不准确;

问题2:为什么sql查询时间那么久。

在仔细查看sql后,问题得到解决。这个问题很简单,来看sql,如下所示:

SELECT
v.ep_id,
COUNT(*)
FROM
dw_l_v v
WHERE
v.id = 'XXX'
AND v.ep_id = 'XXX'
OR v.ep_id = 'XXX'
OR v.ep_id = 'XXX'
OR v.ep_id = 'XXX'
AND v.language = 'zh_cn'
GROUP BY
v.ep_id;

问题给新人解答后,自己有感而发,所以稍加整理了此篇。

sql查询数据不对

依然来看这2个问题,先看问题1,数据不对的问题。

这个问题很好解答,在SQL必知必会的章节中,也有提到该问题。出现这个问题的原因,就在于,数据过滤条件的优先级了。

常用的逻辑运算符有:and / or / not

所对应的优先级为:() > not > and > or

sql在处理OR操作符前,优先处理AND操作符。

由于上述sql没有将OR操作符用小括号提高优先级,从而导致先处理了AND操作符,再来处理OR操作符,最终结果就是数据不准确。

我们将sql修改成如下即可:

SELECT
v.ep_id,
COUNT(*)
FROM
dw_l_v v
WHERE
v.id = 'XXX'
AND (v.ep_id = 'XXX'
OR v.ep_id = 'XXX'
OR v.ep_id = 'XXX'
OR v.ep_id = 'XXX' )
AND v.language = 'zh_cn'
GROUP BY
v.ep_id;

或者ep_id字段条件用IN操作符来处理,修改如下:

SELECT
v.ep_id,
COUNT(*)
FROM
dw_l_v v
WHERE
v.id = 'XXX'
AND v.ep_id IN ('XXX','XXX','XXX','XXX')
AND v.language = 'zh_cn'
GROUP BY
v.ep_id;

sql调整后,再来执行核对数据,数据查询准确。

我们从上述修改的sql看出,IN操作符与OR操作符实现的功能是一样的。的确是这样,最终得到的结果完全一致。

但IN操作符对比OR操作符,还有如下优点:

  • 存在很多合法选项时,IN操作符的语法更清楚、更直观;
  • 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理;
  • IN操作符一般比一组OR操作符执行的更快;
  • IN最大优点是可以包含其他 SELECT 语句,能够动态的建立 WHERE 子句。

sql查询时间久

在解决了sql查询数据不对的问题,我们再来看sql查询花费时间久的问题。

在mysql中,我们可以通过 EXPLAIN 来查看sql的执行计划。我们分别查看修改前跟修改后sql的执行计划,如下所示:

修改前的sql执行计划:

修改后的sql执行计划:

直接拿2张图来对比,为什么查询慢,想必就很清楚了吧,一目了然。

从图中可知,修改前的sql,rows 字段,客户端发送160W+的数据量;而修改后的sql,rows 字段,客户端发送2000+的数据量。先不对比其他的字段,单凭这点就可以看出sql的问题所在了。

由于数量级的差异,从而sql查询的花费时间也就不一样了。

在不修改之前,sql查询的时间要花费15s左右;而修改后的sql查询,查询结果的时间1s都不需要。

从上而知,平时在项目中的sql优化也是很有必要的。

在看完rows字段后,我们再来看个type字段。

通过type字段可以看出,修改前的sql,是使用了全表扫描,所以看到这,也能解答为什么客户端发送了160W+的数据量了,原因就是全表扫描的原因。

mysql执行计划的其他字段,大家可以自行百度了解,今天就先不多聊了。

好了,今天的分享就到这了,文章有误之处,欢迎批评指正。

测试杂谈——一条SQL引发的思考的更多相关文章

  1. 测试杂谈——一条SQL引发的思考(二)

    在前段时间,曾写过一篇关于SQL问题的文章,测试杂谈--一条SQL引发的思考(一). 今天这篇,算是个问题记录吧,问题并不复杂,但对于测试同学而言,确实是个需要关注的点. 问题分析 最近在日常工作中, ...

  2. 曲演杂坛--一条DELETE引发的思考

    原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...

  3. 【数据库】_由2000W多条开房数据引发的思考、实践----给在校生的一个真实【练耙场】,同学们,来开始一次伟大的尝试吧。

      ×   缘起---闲逛博客园 前几天的时候,在某一QQ群看到一条消息“XXX酒店开房XXXBTXX迅雷BT下载”,当时是一目十行的心态浏览,目光掠过时, 第一反应我想多了~以为是XX种子(你懂的~ ...

  4. 一条 SQL 引发的事故,同事直接被开除!!

    前言 Insert into select请慎用. 这天xxx接到一个需求,需要将表A的数据迁移到表B中去做一个备份.本想通过程序先查询查出来然后批量插入.但xxx觉得这样有点慢,需要耗费大量的网络I ...

  5. 一条sql引发的“血案”

    前几天有一个项目要上线,需要对表的一个字段进行扩充,项目经理让我准备脚本,于是我准备了如下的脚本: )); )); )); 结果上线的时候,ord_log1和ord_log2表中有30万数据,在执行的 ...

  6. 同一条sql insert 有时快有时慢 引发的血案

    同一条sql语句,为什么有时插入块,有时插入慢原因剖析 背景:同一条sql ,有时插入时间几毫秒,有时插入时间几十毫秒,为什么? Sql角度:简单insert 表角度: 一个主键 系统参数角度: 开启 ...

  7. 一条SQL在 MaxCompute 分布式系统中的旅程

    摘要:2019杭州云栖大会大数据技术专场,由阿里云资深技术专家侯震宇.阿里云高级技术专家陈颖达以及阿里云资深技术专家戴谢宁共同以“SQL在 MaxCompute 分布式系统中的旅程 ”为题进行了演讲. ...

  8. 解决一道leetcode算法题的曲折过程及引发的思考

    写在前面 本题实际解题过程是 从 40秒 --> 24秒 -->1.5秒 --> 715ms --> 320ms --> 48ms --> 36ms --> ...

  9. 『片段』OracleHelper (支持 多条SQL语句)

    C# 调用 Oracle 是如此尴尬 >System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废. >要链接 Oracle 服务器,必须在 本机安装 ...

随机推荐

  1. PHP中的单引号跟双引号的区别

    不同点: 单引号只能解析转义字符"'"和"\",其他的原样输出.

  2. ◆JAVA加密解密-3DES

    从数据安全谈起       当你使用网银时,是否担心你的银行卡会被盗用?     当你和朋友用QQ进行聊天时,是否担心你的隐私会被泄露?     作为开发者,编写安全的代码比编写优雅的代码更重要,因为 ...

  3. 手写RPC框架(六)整合Netty

    手写RPC框架(六)整合Netty Netty简介: Netty是一个基于NIO的,提供异步,事件驱动的网络应用工具,具有高性能高可靠性等特点. 使用传统的Socket来进行网络通信,服务端每一个连接 ...

  4. Word 模板注入

      要实现word模板注入,需要一个被注入的文档,以及一个注入用的模板. 1.创建一个启用宏的模板   打开word,alt+f8创建编辑宏,在Project->Microsoft Word对象 ...

  5. [LeetCode]剑指 Offer 17. 打印从1到最大的n位数

    输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数 999. 示例 1: 输入: n = 1 输出: [1,2,3,4,5,6,7, ...

  6. 图解|12张图告诉你MySQL的主键查询为什么这么快

    这是图解MySQL的第3篇文章,这篇文章会让大家清楚地明白: 什么是InnoDB行格式?InnoDB页是什么? InnoDB页和InnoDB行格式都有哪些字段信息? 为什么推荐使用自增ID作为主键,而 ...

  7. Eclipse插件开发demo

    一.安装 1. 下载安装JDk 2. 下载安装PDE(Plugin-in Development Environment) 访问eclipse官网,点击Download,选择Download Pack ...

  8. 轩辕展览-VR虚拟展厅设计如何实现全景漫游功能

    什么是在线3d漫游?如何在VR虚拟展厅设计之中实现3d漫游功能?让我们来分享3dVR虚拟展厅的在线漫游. 实际上,在线3d漫游就是通过3d仿真场景,使用鼠标和键盘在虚拟空间之中自由漫游,它可以从高空俯 ...

  9. 入门pwn的练习

    都是比较简单的一些pwn的题目,也是团队里面的一个人发着做的,因为是初学,所以就还是先从简单的向难得方向去发展. 第一个 先用checksec或者die检测一下, 然后拖入到IDA,shift+f12 ...

  10. RFC2899广播吞吐量测试——网络测试仪实操

    一.简介 RFC 2889为LAN交换设备的基准测试提供了方法学,它将RFC 2544中为网络互联设备基准测试所定义的方法学扩展到了交换设备,提供了交换机转发性能(Forwarding Perform ...