日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍。以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写。

先看下我的表结构:

CREATE TABLE `d_sku` (
`id` varchar() NOT NULL,
`commodity_id` varchar() DEFAULT NULL,
`counts` int() DEFAULT NULL,
`price` double(,) DEFAULT NULL,
`status` int() DEFAULT NULL,
`location` varchar() DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`create_id` varchar() DEFAULT NULL,
`modify_time` datetime DEFAULT NULL,
`provalue_str` varchar() DEFAULT NULL,
`category_id` varchar() DEFAULT NULL,
`customer_id` varchar() DEFAULT NULL,
`cert_no` varchar() DEFAULT NULL,
`profit` double DEFAULT NULL,
`check_cargo` int() DEFAULT '',
`check_time` datetime DEFAULT NULL,
`keep_last_checked` int() DEFAULT NULL,
`approval_status` int() DEFAULT '',
`code` varchar() DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_price` (`price`) USING BTREE,
KEY `index_category_status` (`category_id`,`status`) USING BTREE,
KEY `index_modifytime` (`modify_time`) USING BTREE,
KEY `index_customerId_categoryId` (`customer_id`,`category_id`) USING BTREE,
KEY `index_certNo_customerId` (`cert_no`,`customer_id`) USING BTREE,
KEY `index_provaluestr` (`provalue_str`()) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

一个电商平台的SKU数据库表结构模式,该表中数据条数376138。以此下两种查询方式看下执行效率。查询语句都是从该表中查询一条数据分类为d2a17030-149d-11e5-a9de-000c29d7a3a0并且编号为5186354366的数据。

1.实例测试

1.对查询内容添加单引号

SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and  d.cert_no='';

【消息】:执行成功,当前返回:[1]行,耗时:[1ms.]。查询速度非常快。

2.对查询内容不添加单引号

SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and  d.cert_no=;

【消息】:执行成功,当前返回:[1]行,耗时:[1210ms.]发现两者之间的执行效率显而易见啊。

2.两者区别分析

这样一查询效果真的是显而易见,添加单引号查询才1ms,不添加单引号查询的耗时是1210ms.一条数据就这么明显了。可想而知这种性能损失有多大。但是为什么会这样呢?先从分析索引看起。使用关键词 “explain” 查看sql执行效率详细(关键词使用介绍点传送门)。

explain  SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and  d.cert_no='';

explain  SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and  d.cert_no=;

图一:添加单引号

图二:未添加单引号

两条数据对比分析:

图一:

添加单引号后的性能详情,其中表头key这里显示出来真正使用了组合索引“index_certNo_customerId” ,其中这两个索引对应的列正好是“category_id”和“cert_no”。再看rows这,表示查询这条数据只检索了一条数据,因为是这里索引生效了,所以通过“cert_no”编号直接查询到了数据。

图二:

未添加单引号后的性能详情,发现真正使用的索引只有“index_category_status”,回到创建表结构的时候可以发现这条索引信息是添加`category_id`,`status`这两个列的,表示只用到了category_id,而第二个条件的cert_no列并没有用到索引,所以性能的损耗就在这里发生了。

总结:

原因就是因为我们创建表结构的时候cert_no字段是varchar类型的,而where时未添加单引号的时候参数是被做为数字类型来使用的,那不同的类型做查询的时候肯定是要转型的,数据类型转换的话就无法正常使用索引了。所以可以得到一个结论就是Int类型的数据在转换varchar再使用是不会使用索引的。我们可以修改表结构将cert_no改为int类型后在使用不添加单引号的参数查询时性能也就是正常的了。同样也是可以通过添加单引号来实现。

Mysql中where条件一个单引号引发的性能损耗的更多相关文章

  1. sql中 查询条件出现单引号和特殊字符处理

    1.两个单引号转为一个单引号 example:  select * from tb where  name=' '' ' 2.如果出现 "_","%"  需要用 ...

  2. Mysql中反引号和单引号的区别

    反引号,一般在ESC键的下方. 它是为了区分MYSQL的保留字与普通字符而引入的符号.举个例子:SELECT `select` FROM `test` WHERE select='字段值'在test表 ...

  3. MyBatis中的条件判断单引号双引号的使用

    对于字符串判断, <if test="aIn != 'A'" >会出现问题,系统会试图把'A'转成数字,改为 <if test='aIn != "A&q ...

  4. Mysql中的条件语句if、case

    Mysql中的条件语句在我们对数据进行转换的时候比较有用,这样就不需要创建中转表. IF 函数 IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> ...

  5. json.loads()的字符串中为单引号引发的错误

    如下错误属于弱智错误,但是错的原因让我无语,所以记录一下 str2="{'card':6217001650004184441}"print(json.loads(str2)) Tr ...

  6. 【python】sql语句插入中内容同时包含单引号和双引号的解决办法

    在python中调用MySQLdb模块插入数据信息,假设待输入信息data为: Hello'World"! 其中同时包含了单引号和双引号 一般插入语句为 sql = "insert ...

  7. mysql 字段引号那个像单引号的撇号用法

    我们知道通常的SQL查询语句是这么写的: select col from table; 这当然没问题,但如果字段名是“from”呢? select from from table; 若真的这么写,必然 ...

  8. Excel公式中双引号和单引号输入和显示以及函数的选择确认

    [Excel中显示双引号] 1.直接输入双引号“”或单引号“ 2.工式中显示双引号需输入“”“”“”(六个引号)或单引号需输入“”“”(四个引号) [Excel中快速确认已选择的函数] 1.用键盘的上 ...

  9. 菜菜小问题——python中print函数 以及单引号、双引号、三引号

    直接面对——引号,就是为了保证打印出来的东东符合预期 如:print("小菜菜") 结果是: .================1========================= ...

随机推荐

  1. Docker Mysql主从同步配置搭建

    Docker Mysql主从同步配置搭建 建立目录 在虚拟机中建立目录,例如路径/home/mysql/master/data,目录结构如下: Linux中 新建文件夹命令:mkdir 文件夹名 返回 ...

  2. springmvc4开发rest

    Spring MVC 4 RESTFul Web Services CRUD Example+RestTemplate Created on:  August 11, 2015  | Last upd ...

  3. Docker Win 10 安装

    最近了解了一下Docker,不看不知道,一了解就完全被它给吸引住了.以往要装个环境,除了要准备一个Linux系统,然后在安装各种版本的类库,再安装我们需要各种应用服务(如Redis,Ngix,Mong ...

  4. 最小二乘法多项式拟合的Java实现

    背景 由项目中需要根据一些已有数据学习出一个y=ax+b的一元二项式,给定了x,y的一些样本数据,通过梯度下降或最小二乘法做多项式拟合得到a.b,解决该问题时,首先想到的是通过spark mllib去 ...

  5. Linux:sheel脚本for的用法,及日期参数+1day用法

    记录下shell的for的用法,及参数是日期的情况下,该日期+1day的用法: #!/usr/bin/env bash source /app/catt/login.sh p_days="2 ...

  6. Struts(二十三):使用声名式验证

    Struts2工程中的验证分为两种: 1.基于XWork Validation Framework的声明式验证:Struts2提供了一些基于XWork Validation Framework的内建验 ...

  7. Struts(十九):类型转换、类型转换错误消息及显示

    类型转换概念 1.从html表单页面到一个Action对象,类型转化是从字符串到一个非字符串:html并没有“类型”的概念,每个表单输入的信息都只可能是一个字符串或者一个字符串数组,但是在服务器端,必 ...

  8. [js]关于call()和apply()的理解

    call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向. 因为 JavaScript 的函数存在「定义时上下文」和 ...

  9. window下编辑了脚本文件linux报如下错误

    首先vi :set ff 查看文件类型 接着 下载dos2unix  root用户下yum -y install dos2unix 然后 dos2unix 文件.sh 转换格式  接着在正常启动即可

  10. drupal 8 建立我的相册

    一.先建一个存图片的内容类型 1.创建内容类型 点击[结构]>[内容类型]>[+add content type] 点击[保存和管理字段] 2.添加字段 点击[+添加字段] 点击[保存并继 ...