日常写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. sts 和 lombok

    1.安装lombok.jar到sts.exe所在目录 如果是eclipse,需要放到eclipse.exe所在目录,同理myeclipse. 2.修改sts.ini配置使用lombok 如果是ecli ...

  2. Spring Security 入门(1-4-1)Spring Security - 认证过程

    理解时可结合一下这位老兄的文章:http://www.importnew.com/20612.html 1.Spring Security的认证过程 1.1.登录过程 - 如果用户直接访问登录页面 用 ...

  3. QT5.5与MYSQL5.6数据库连接的具体方法与实现

    由于毕设需要用到QT读取数据库中的数据,并将数据保存至数据库中.花了一天的时间,总算实现了从QT中读取数据库中的数据.网上相关资料很多,但是写得不是很全,中间出现了一些问题,解决起来比较麻烦.所以本文 ...

  4. android- 远程调试

    最近由于要在另外一台android设备上调试代码,在本机PC上查看其log.两台机器离的比较远, 无法用usb直接连接,于是在网上找了很多资料,最找使用adb connect方法解决了该问题.解决过程 ...

  5. TreeMap就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...

  6. bs4解析要获取被注掉的部分需先将注释符号去掉

    <div class="xzcf-content"> <div id="sfxz"> <div class="main- ...

  7. global关键字修改全局变量

    #我们知道全局变量在函数外部,强烈建议不要在函数内部修改全局变量,正常情况下,在函数内部改变全局变量并不影响全局变量的值,举例如下 count = 5 >>> def myfun() ...

  8. javascript实现图片延迟加载方法汇总(三种方法)

    看到一些大型网站,页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片则不加载,一定程序上加快了页面加载的速度,跟着小编一 ...

  9. 【贪心】Codeforces 349B.Color the Fence题解

    题目链接:http://codeforces.com/problemset/problem/349/B 题目大意 小明要从9个数字(1,2,--,9)去除一些数字拼接成一个数字,是的这个数字最大. 但 ...

  10. MySQL集合操作类型

    SQL语言包含3个集合操作符(union.intersect.expect)以执行各种集合操作. 此外,每个集合操作符可以有两种修饰符:一个表是包含重复项,另一个表是去除重复项(但不一定时所有的重复项 ...