日常写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. 新概念英语(1-99)Ow!

    Lesson 99 Owl! 啊哟! Listen to the tape then answer this question. Must Andy go to see the doctor?听录音, ...

  2. hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(4)SPARK 安装

    hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(4)SPARK 安装 一.依赖文件安装 1.1 JDK 参见博文:http://www.cnblogs.com/liugh ...

  3. python实现 字符串匹配函数

    通配符是 shell 命令中的重要功能,? 表示匹配任意 1 个字符,*表示匹配 0 个或多个字符.请使用你熟悉的编程语言实现一个字符串匹配函数,支持 ? 和 * 通配符.如 "a?cd*d ...

  4. python网络编程基础(一)

    一.C/S架构 客户端/服务端架构 二.OSI七层架构 七层模型,亦称OSI(Open System Interconnection)参考模型,是参考模型是国际标准化组织(ISO)制定的一个用于计算机 ...

  5. Python系列-python内置函数

    abs(x) 返回数字的绝对值,参数可以是整数.也可以是浮点数.如果是复数,则返回它的大小 all(iterable) 对参数中的所有元素进行迭代,如果所有的元素都是True,则返回True,函数等价 ...

  6. vuex commit保存数据技巧

    vuex 单向数据流,推荐的commit 改变state数据,写起来非常繁琐,因为改数据可能要写很多commit函数. 依据我的理解,单向数据流主要是为了避免数据混乱,便于调试. 说白了,就是一个数据 ...

  7. scrapy中的request

    scrapy中的request 初始化参数 class scrapy.http.Request( url [ , callback, method='GET', headers, body, cook ...

  8. 基于angularJS搭建的管理系统

    前言 angularJS搭建的系统,是一年前用的技术栈,有些地方比较过时,这里只是介绍实现思路 前端架构 工程目录 项目浅析 项目依赖包配置package.json { "name" ...

  9. java代码优化细节

    在代码线上运行的过程中,往往会出现很多我们意想不到的错误,不少错误定位到最后往往是一个非常小的原因导致的.然而因为线上环境和开发环境是非常不同的,为了解决一个错误,我们需要先查找错误原因.修改验证.打 ...

  10. [LeetCode] Couples Holding Hands 两两握手

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...